List:Commits« Previous MessageNext Message »
From:Mikael Ronstrom Date:January 23 2012 1:56pm
Subject:bzr push into mysql-5.5-cluster-7.2 branch (mikael.ronstrom:3720 to 3722)
View as plain text  
 3722 Mikael Ronstrom	2012-01-23 [merge]
      merge

    added:
      storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/StressTest.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordBlobImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordOperationImpl.java
      storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/StressTest.java
      storage/ndb/src/kernel/vm/CountingPool.cpp
      storage/ndb/src/kernel/vm/CountingPool.hpp
    modified:
      mysql-test/suite/ndb/t/clusterj.test
      storage/ndb/clusterj/clusterj-api/pom.xml
      storage/ndb/clusterj/clusterj-bindings/pom.xml
      storage/ndb/clusterj/clusterj-core/pom.xml
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/SessionImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/DomainFieldHandlerImpl.java
      storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/Operation.java
      storage/ndb/clusterj/clusterj-jdbc/pom.xml
      storage/ndb/clusterj/clusterj-jpatest/pom.xml
      storage/ndb/clusterj/clusterj-openjpa/pom.xml
      storage/ndb/clusterj/clusterj-test/pom.xml
      storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/DynamicObjectTest.java
      storage/ndb/clusterj/clusterj-test/src/main/resources/schema.sql
      storage/ndb/clusterj/clusterj-tie/pom.xml
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/BlobImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterConnectionImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterConnectionServiceImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterTransactionImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ColumnImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DbImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DictionaryImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java
      storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/Utility.java
      storage/ndb/clusterj/clusterj-tie/src/main/resources/com/mysql/clusterj/tie/Bundle.properties
      storage/ndb/clusterj/pom.xml
      storage/ndb/include/ndbapi/Ndb.hpp
      storage/ndb/include/ndbapi/NdbDictionary.hpp
      storage/ndb/include/ndbapi/NdbOperation.hpp
      storage/ndb/include/ndbapi/NdbScanOperation.hpp
      storage/ndb/src/common/transporter/TransporterRegistry.cpp
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
      storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp
      storage/ndb/src/kernel/vm/CMakeLists.txt
      storage/ndb/src/kernel/vm/Pool.cpp
      storage/ndb/src/kernel/vm/Pool.hpp
      storage/ndb/src/ndbjtie/NdbApiWrapper.hpp
      storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/Ndb.java
      storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbDictionary.java
      storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbOperation.java
      storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbOperationConst.java
      storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbScanOperation.java
      storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/issues.txt
      storage/ndb/src/ndbjtie/ndbapi_jtie.hpp
      storage/ndb/test/ndbapi/testSystemRestart.cpp
 3721 Mikael Ronstrom	2012-01-23
      Upgraded flexAsynch to support 511 attributes

    modified:
      storage/ndb/test/ndbapi/flexAsynch.cpp
 3720 Mikael Ronstrom	2012-01-23
      Remove unnecessary eternal while-loop

    modified:
      storage/ndb/src/kernel/vm/mt.cpp
=== modified file 'mysql-test/suite/ndb/t/clusterj.test'
--- a/mysql-test/suite/ndb/t/clusterj.test	revid:mikael.ronstrom@stripped
+++ b/mysql-test/suite/ndb/t/clusterj.test	revid:mikael.ronstrom@stripped
@@ -49,6 +49,7 @@ DROP TABLE longlongstringfk;
 DROP TABLE longlongstringpk;
 DROP TABLE longvarbinarypk;
 DROP TABLE nullvalues;
+DROP TABLE stress;
 DROP TABLE stringtype;
 DROP TABLE t_basic;
 DROP TABLE timestamptypes;

=== modified file 'storage/ndb/clusterj/clusterj-api/pom.xml'
--- a/storage/ndb/clusterj/clusterj-api/pom.xml	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-api/pom.xml	revid:mikael.ronstrom@stripped
@@ -20,13 +20,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.19-SNAPSHOT</version>
+    <version>7.1.20-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-api</artifactId>
   <packaging>bundle</packaging>
-  <version>7.1.19-SNAPSHOT</version>
+  <version>7.1.20-SNAPSHOT</version>
   <name>ClusterJ API</name>
   <description>The API for ClusterJ</description>
   <build>

=== modified file 'storage/ndb/clusterj/clusterj-bindings/pom.xml'
--- a/storage/ndb/clusterj/clusterj-bindings/pom.xml	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-bindings/pom.xml	revid:mikael.ronstrom@stripped
@@ -20,13 +20,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.19-SNAPSHOT</version>
+    <version>7.1.20-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-bindings</artifactId>
   <packaging>bundle</packaging>
-  <version>7.1.19-SNAPSHOT</version>
+  <version>7.1.20-SNAPSHOT</version>
   <name>ClusterJ Bindings</name>
   <description>The ndb-bindings implementation of ClusterJ storage spi</description>
   <build>

=== modified file 'storage/ndb/clusterj/clusterj-core/pom.xml'
--- a/storage/ndb/clusterj/clusterj-core/pom.xml	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-core/pom.xml	revid:mikael.ronstrom@stripped
@@ -20,13 +20,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.19-SNAPSHOT</version>
+    <version>7.1.20-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-core</artifactId>
   <packaging>bundle</packaging>
-  <version>7.1.19-SNAPSHOT</version>
+  <version>7.1.20-SNAPSHOT</version>
   <name>ClusterJ Core</name>
   <description>The core implementation of ClusterJ</description>
   <build>

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/SessionImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/SessionImpl.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/SessionImpl.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2009, 2012, 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
@@ -392,8 +392,10 @@ public class SessionImpl implements Sess
             storeTable = domainTypeHandler.getStoreTable();
             op = clusterTransaction.getInsertOperation(storeTable);
             // set all values in the operation, keys first
+            op.beginDefinition();
             domainTypeHandler.operationSetKeys(valueHandler, op);
             domainTypeHandler.operationSetModifiedNonPKValues(valueHandler, op);
+            op.endDefinition();
             // reset modified bits in instance
             domainTypeHandler.objectResetModified(valueHandler);
         } catch (ClusterJUserException cjuex) {

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/DomainFieldHandlerImpl.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/DomainFieldHandlerImpl.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/metadata/DomainFieldHandlerImpl.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2010, 2012, 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
@@ -311,8 +311,6 @@ public class DomainFieldHandlerImpl exte
     public DomainFieldHandlerImpl(
             DomainTypeHandlerImpl<?> domainTypeHandler, Table table, int i,
             com.mysql.clusterj.core.store.Column storeColumn) {
-        if (logger.isDebugEnabled()) logger.debug("new dynamic DomainFieldHandlerImpl: " +
-                "fieldNumber: " + fieldNumber + "; name:" + name);
         this.domainTypeHandler = domainTypeHandler;
         this.fieldNumber = i;
         this.storeColumn = storeColumn;
@@ -325,7 +323,7 @@ public class DomainFieldHandlerImpl exte
                 case Int:
                 case Unsigned:
                     this.objectOperationHandlerDelegate = objectOperationHandlerKeyInt;
-                    this.type = Integer.class;
+                    this.type = int.class;
                     break;
                 case Char:
                 case Varchar:
@@ -335,7 +333,7 @@ public class DomainFieldHandlerImpl exte
                 case Bigint:
                 case Bigunsigned:
                     this.objectOperationHandlerDelegate = objectOperationHandlerKeyLong;
-                    this.type = Long.class;
+                    this.type = long.class;
                     break;
                 case Binary:
                 case Varbinary:
@@ -350,16 +348,26 @@ public class DomainFieldHandlerImpl exte
             switch (this.storeColumnType) {
                 case Bigint:
                 case Bigunsigned:
-                    this.objectOperationHandlerDelegate = objectOperationHandlerObjectLong;
-                    this.type = Long.class;
+                    if (storeColumn.getNullable()) {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerObjectLong;
+                        this.type = Long.class;
+                    } else {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerLong;
+                        this.type = long.class;
+                    }
                     break;
                 case Binary:
                     this.objectOperationHandlerDelegate = objectOperationHandlerBytes;
                     this.type = byte[].class;
                     break;
                 case Bit:
-                    this.objectOperationHandlerDelegate = objectOperationHandlerObjectLong;
-                    this.type = Long.class;
+                    if (storeColumn.getNullable()) {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerObjectLong;
+                        this.type = Long.class;
+                    } else {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerLong;
+                        this.type = long.class;
+                    }
                     break;
                 case Blob:
                     this.objectOperationHandlerDelegate = objectOperationHandlerBytesLob;
@@ -383,16 +391,31 @@ public class DomainFieldHandlerImpl exte
                     this.type = BigDecimal.class;
                     break;
                 case Double:
-                    this.objectOperationHandlerDelegate = objectOperationHandlerObjectDouble;
-                    this.type = Double.class;
+                    if (storeColumn.getNullable()) {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerObjectDouble;
+                        this.type = Double.class;
+                    } else {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerDouble;
+                        this.type = double.class;
+                    }
                     break;
                 case Float:
-                    this.objectOperationHandlerDelegate = objectOperationHandlerObjectFloat;
-                    this.type = Float.class;
+                    if (storeColumn.getNullable()) {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerObjectFloat;
+                        this.type = Float.class;
+                    } else {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerFloat;
+                        this.type = float.class;
+                    }
                     break;
                 case Int:
-                    this.objectOperationHandlerDelegate = objectOperationHandlerObjectInteger;
-                    this.type = Integer.class;
+                    if (storeColumn.getNullable()) {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerObjectInteger;
+                        this.type = Integer.class;
+                    } else {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerInt;
+                        this.type = int.class;
+                    }
                     break;
                 case Longvarbinary:
                     this.objectOperationHandlerDelegate = objectOperationHandlerBytes;
@@ -404,8 +427,13 @@ public class DomainFieldHandlerImpl exte
                     break;
                 case Mediumint:
                 case Mediumunsigned:
-                    this.objectOperationHandlerDelegate = objectOperationHandlerObjectInteger;
-                    this.type = Integer.class;
+                    if (storeColumn.getNullable()) {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerObjectInteger;
+                        this.type = Integer.class;
+                    } else {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerInt;
+                        this.type = int.class;
+                    }
                     break;
                 case Olddecimal:
                     error(local.message("ERR_Unsupported_Field_Type", "Olddecimal", name));
@@ -417,8 +445,13 @@ public class DomainFieldHandlerImpl exte
                     break;
                 case Smallint:
                 case Smallunsigned:
-                    this.objectOperationHandlerDelegate = objectOperationHandlerObjectShort;
-                    this.type = Short.class;
+                    if (storeColumn.getNullable()) {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerObjectShort;
+                        this.type = Short.class;
+                    } else {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerShort;
+                        this.type = short.class;
+                    }
                     break;
                 case Text:
                     this.objectOperationHandlerDelegate = objectOperationHandlerStringLob;
@@ -434,17 +467,26 @@ public class DomainFieldHandlerImpl exte
                     break;
                 case Tinyint:
                 case Tinyunsigned:
-                    this.objectOperationHandlerDelegate = objectOperationHandlerObjectByte;
-                    this.type = Byte.class;
+                    if (storeColumn.getNullable()) {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerObjectByte;
+                        this.type = Byte.class;
+                    } else {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerByte;
+                        this.type = byte.class;
+                    }
                     break;
                 case Undefined:
                     error(local.message("ERR_Unsupported_Field_Type", "Undefined", name));
                     objectOperationHandlerDelegate = objectOperationHandlerUnsupportedType;
                     break;
                 case Unsigned:
-                    this.objectOperationHandlerDelegate = objectOperationHandlerObjectInteger;
-                    this.type = Integer.class;
-                    break;
+                    if (storeColumn.getNullable()) {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerObjectInteger;
+                        this.type = Integer.class;
+                    } else {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerInt;
+                        this.type = int.class;
+                    }
                 case Varbinary:
                     this.objectOperationHandlerDelegate = objectOperationHandlerBytes;
                     this.type = byte[].class;
@@ -454,14 +496,21 @@ public class DomainFieldHandlerImpl exte
                     this.type = String.class;
                     break;
                 case Year:
-                    this.objectOperationHandlerDelegate = objectOperationHandlerObjectShortYear;
-                    this.type = Short.class;
+                    if (storeColumn.getNullable()) {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerObjectShort;
+                        this.type = Short.class;
+                    } else {
+                        this.objectOperationHandlerDelegate = objectOperationHandlerShort;
+                        this.type = short.class;
+                    }
                     break;
                 default:
                     error(local.message("ERR_Unsupported_Field_Type", this.storeColumnType, name));
                     objectOperationHandlerDelegate = objectOperationHandlerUnsupportedType;
             }
         }
+        if (logger.isDebugEnabled()) logger.debug("new dynamic DomainFieldHandlerImpl: " +
+                "fieldNumber: " + fieldNumber + "; name: " + name + "; type: " + type);
         nullValueDelegate = nullValueNONE;
         registerIndices(domainTypeHandler);
         reportErrors();

=== modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/Operation.java'
--- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/Operation.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/Operation.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2009, 2012, 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
@@ -85,4 +85,8 @@ public interface Operation {
 
     public void setString(Column storeColumn, String string);
 
+    public void beginDefinition();
+
+    public void endDefinition();
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-jdbc/pom.xml'
--- a/storage/ndb/clusterj/clusterj-jdbc/pom.xml	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-jdbc/pom.xml	revid:mikael.ronstrom@stripped
@@ -19,13 +19,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.19-SNAPSHOT</version>
+    <version>7.1.20-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>clusterj</groupId>
   <artifactId>clusterj-jdbc</artifactId>
   <name>ClusterJ JDBC Plugin</name>
-  <version>7.1.19-SNAPSHOT</version>
+  <version>7.1.20-SNAPSHOT</version>
   <dependencies>
     <dependency>
       <groupId>junit</groupId>

=== modified file 'storage/ndb/clusterj/clusterj-jpatest/pom.xml'
--- a/storage/ndb/clusterj/clusterj-jpatest/pom.xml	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-jpatest/pom.xml	revid:mikael.ronstrom@stripped
@@ -28,12 +28,12 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.19-SNAPSHOT</version>
+    <version>7.1.20-SNAPSHOT</version>
   </parent>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-jpatest</artifactId>
-    <version>7.1.19-SNAPSHOT</version>
+    <version>7.1.20-SNAPSHOT</version>
     <packaging>jar</packaging>
     <name>ClusterJ JPA Integration Tests</name>
 

=== modified file 'storage/ndb/clusterj/clusterj-openjpa/pom.xml'
--- a/storage/ndb/clusterj/clusterj-openjpa/pom.xml	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-openjpa/pom.xml	revid:mikael.ronstrom@stripped
@@ -24,12 +24,12 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.19-SNAPSHOT</version>
+    <version>7.1.20-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-openjpa</artifactId>
-  <version>7.1.19-SNAPSHOT</version>
+  <version>7.1.20-SNAPSHOT</version>
   <packaging>bundle</packaging>
   <name>ClusterJ OpenJPA Integration</name>
 

=== modified file 'storage/ndb/clusterj/clusterj-test/pom.xml'
--- a/storage/ndb/clusterj/clusterj-test/pom.xml	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-test/pom.xml	revid:mikael.ronstrom@stripped
@@ -20,13 +20,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.19-SNAPSHOT</version>
+    <version>7.1.20-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-test</artifactId>
   <packaging>jar</packaging>
-  <version>7.1.19-SNAPSHOT</version>
+  <version>7.1.20-SNAPSHOT</version>
   <name>ClusterJ Test Suite</name>
   <build>
     <plugins>

=== modified file 'storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/DynamicObjectTest.java'
--- a/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/DynamicObjectTest.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/DynamicObjectTest.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2010, 2012, 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
@@ -40,7 +40,7 @@ public class DynamicObjectTest extends A
 
     private Object[] expectedTBasicTypes = new Object[] {ColumnType.Int, ColumnType.Varchar, ColumnType.Int, ColumnType.Int};
 
-    private Object[] expectedTBasicJavaTypes = new Object[] {Integer.class, String.class, Integer.class, Integer.class};
+    private Object[] expectedTBasicJavaTypes = new Object[] {int.class, String.class, Integer.class, int.class};
 
     private Object[] expectedTBasicMaximumLengths = new Object[] {1, 32, 1, 1};
 

=== added file 'storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/StressTest.java'
--- a/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/StressTest.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-test/src/main/java/testsuite/clusterj/StressTest.java	revid:mikael.ronstrom@stripped
@@ -0,0 +1,199 @@
+/*
+   Copyright (c) 2012, 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 org.junit.Ignore;
+
+import com.mysql.clusterj.ClusterJFatalUserException;
+import com.mysql.clusterj.ColumnMetadata;
+import com.mysql.clusterj.DynamicObject;
+
+import testsuite.clusterj.AbstractClusterJModelTest;
+import testsuite.clusterj.model.IdBase;
+
+@Ignore
+public class StressTest extends AbstractClusterJModelTest {
+
+    static protected final Runtime rt = Runtime.getRuntime();
+
+    private static final int NUMBER_TO_INSERT = 4000;
+
+    private static final int ITERATIONS = 5;
+
+    private static final String tableName = "stress";
+
+    private ColumnMetadata[] columnMetadatas;
+
+    private Timer timer = new Timer();
+
+    @Override
+    java.lang.Class<? extends IdBase> getModelClass() {
+        return Stress.class;
+    }
+
+    @Override
+    public void localSetUp() {
+        createSessionFactory();
+        session = sessionFactory.getSession();
+        tx = session.currentTransaction();
+        session.deletePersistentAll(Stress.class);
+        columnMetadatas = session.newInstance(Stress.class).columnMetadata();
+    }
+
+    public void testInsAattr_indy() {
+        long total = 0;
+        for (int i = 0; i < ITERATIONS; ++i) {
+            // garbage collect what we can before each test
+            gc();
+            timer.start();
+            for (int key = 0; key < NUMBER_TO_INSERT; ++key) {
+                Stress instance = createObject(key);
+                session.makePersistent(instance);
+            }
+            // drop the first iteration
+            timer.stop();
+            if (i > 0) total += timer.time();
+            System.out.println("testInsAattr_indy: " + timer.time());
+        }
+        System.out.println("Average: " + total/(ITERATIONS - 1) + "\n");
+    }
+
+    public void testInsAattr_each() {
+        long total = 0;
+        for (int i = 0; i < ITERATIONS; ++i) {
+            // garbage collect what we can before each test
+            gc();
+            timer.start();
+            session.currentTransaction().begin();
+            for (int key = 0; key < NUMBER_TO_INSERT; ++key) {
+                Stress instance = createObject(key);
+                session.makePersistent(instance);
+                session.flush();
+            }
+            session.currentTransaction().commit();
+            // drop the first iteration
+            timer.stop();
+            if (i > 0) total += timer.time();
+            System.out.println("testInsAattr_each: " + timer.time());
+        }
+        System.out.println("Average: " + total/(ITERATIONS - 1) + "\n");
+    }
+
+    public void testInsAattr_bulk() {
+        long total = 0;
+        for (int i = 0; i < ITERATIONS; ++i) {
+            // garbage collect what we can before each test
+            gc();
+            timer.start();
+            session.currentTransaction().begin();
+            for (int key = 0; key < NUMBER_TO_INSERT; ++key) {
+                Stress instance = createObject(key);
+                session.makePersistent(instance);
+            }
+            session.currentTransaction().commit();
+            // drop the first iteration
+            timer.stop();
+            if (i > 0) total += timer.time();
+            System.out.println("testInsAattr_bulk: " + timer.time());
+        }
+        System.out.println("Average: " + total/(ITERATIONS - 1) + "\n");
+    }
+
+    protected Stress createObject(int key) {
+        Stress instance = session.newInstance(Stress.class, key);
+        for (int columnNumber = 0; columnNumber < columnMetadatas.length; ++columnNumber) {
+            Object value = null;
+            // create value based on java type
+            ColumnMetadata columnMetadata = columnMetadatas[columnNumber];
+            if (columnMetadata.isPrimaryKey()) {
+                // we have already set the value of the primary key in newInstance
+                continue;
+            }
+            Class<?> cls = columnMetadata.javaType();
+            if (int.class == cls) {
+                value = key;
+            } else if (long.class == cls) {
+                value = (long)key;
+            } else if (float.class == cls) {
+                value = (float)key;
+            } else if (double.class == cls) {
+                value = (double)key;
+            } else {
+                throw new ClusterJFatalUserException("Unsupported column type " + cls.getName()
+                        + " for column " + columnMetadata.name());
+            }
+            instance.set(columnNumber, value);
+        }
+        return instance;
+    }
+
+    public static class Stress extends DynamicObject implements IdBase {
+        public Stress() {}
+
+        public String table() {
+            return tableName;
+        }
+
+        public int getId() {
+            return (Integer) get(0);
+        }
+
+        public void setId(int id) {
+            set(0, id);
+        }
+    }
+
+    static private void gc() {
+        // empirically determined limit after which no further
+        // reduction in memory usage has been observed
+        //final int nFullGCs = 5;
+        final int nFullGCs = 10;
+        for (int i = 0; i < nFullGCs; i++) {
+            //out.print("gc: ");
+            long oldfree;
+            long newfree = rt.freeMemory();
+            do {
+                oldfree = newfree;
+                rt.runFinalization();
+                rt.gc();
+                newfree = rt.freeMemory();
+                //out.print('.');
+            } while (newfree > oldfree);
+            //out.println();
+        }
+    }
+
+    private static class Timer {
+
+        private long time;
+
+        public void start() {
+            time = System.nanoTime() / 1000000;
+        }
+
+        public long stop() {
+            time = (System.nanoTime() / 1000000) - time;
+            return time;
+        }
+
+        public long time() {
+            return time;
+        }
+    }
+
+}

=== modified file 'storage/ndb/clusterj/clusterj-test/src/main/resources/schema.sql'
--- a/storage/ndb/clusterj/clusterj-test/src/main/resources/schema.sql	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-test/src/main/resources/schema.sql	revid:mikael.ronstrom@stripped
@@ -706,6 +706,91 @@ create table longintstringix (
  KEY idx_long_int_string (longix, intix, stringix)
 ) ENGINE=ndbcluster DEFAULT CHARSET=latin1;
 
+drop table if exists stress;
+create table stress (
+  id int not null primary key,
+  i0 int not null,
+  l0 bigint not null,
+  f0 float not null,
+  d0 double not null,
+  i1 int not null,
+  l1 bigint not null,
+  f1 float not null,
+  d1 double not null,
+  i2 int not null,
+  l2 bigint not null,
+  f2 float not null,
+  d2 double not null,
+  i3 int not null,
+  l3 bigint not null,
+  f3 float not null,
+  d3 double not null,
+  i4 int not null,
+  l4 bigint not null,
+  f4 float not null,
+  d4 double not null,
+  i5 int not null,
+  l5 bigint not null,
+  f5 float not null,
+  d5 double not null,
+  i6 int not null,
+  l6 bigint not null,
+  f6 float not null,
+  d6 double not null,
+  i7 int not null,
+  l7 bigint not null,
+  f7 float not null,
+  d7 double not null,
+  i8 int not null,
+  l8 bigint not null,
+  f8 float not null,
+  d8 double not null,
+  i9 int not null,
+  l9 bigint not null,
+  f9 float not null,
+  d9 double not null,
+  i10 int not null,
+  l10 bigint not null,
+  f10 float not null,
+  d10 double not null,
+  i11 int not null,
+  l11 bigint not null,
+  f11 float not null,
+  d11 double not null,
+  i12 int not null,
+  l12 bigint not null,
+  f12 float not null,
+  d12 double not null,
+  i13 int not null,
+  l13 bigint not null,
+  f13 float not null,
+  d13 double not null,
+  i14 int not null,
+  l14 bigint not null,
+  f14 float not null,
+  d14 double not null,
+  i15 int not null,
+  l15 bigint not null,
+  f15 float not null,
+  d15 double not null,
+  i16 int not null,
+  l16 bigint not null,
+  f16 float not null,
+  d16 double not null,
+  i17 int not null,
+  l17 bigint not null,
+  f17 float not null,
+  d17 double not null,
+  i18 int not null,
+  l18 bigint not null,
+  f18 float not null,
+  d18 double not null,
+  i19 int not null,
+  l19 bigint not null,
+  f19 float not null,
+  d19 double not null
+  ) ENGINE=ndbcluster;
+
 create database if not exists test2;
 use test2;
 drop table if exists t_basic2;

=== modified file 'storage/ndb/clusterj/clusterj-tie/pom.xml'
--- a/storage/ndb/clusterj/clusterj-tie/pom.xml	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/pom.xml	revid:mikael.ronstrom@stripped
@@ -20,13 +20,13 @@
   <parent>
     <groupId>com.mysql.clusterj</groupId>
     <artifactId>clusterj-aggregate</artifactId>
-    <version>7.1.19-SNAPSHOT</version>
+    <version>7.1.20-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-tie</artifactId>
   <packaging>bundle</packaging>
-  <version>7.1.19-SNAPSHOT</version>
+  <version>7.1.20-SNAPSHOT</version>
   <name>ClusterJ Tie</name>
   <description>The ndbj-tie implementation of ClusterJ storage spi</description>
   <build>

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/BlobImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/BlobImpl.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/BlobImpl.java	revid:mikael.ronstrom@stripped
@@ -1,6 +1,5 @@
 /*
- *  Copyright 2010 Sun Microsystems, Inc.
- *  All rights reserved. Use is subject to license terms.
+ *  Copyright (c) 2010, 2012, 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
@@ -43,7 +42,11 @@ class BlobImpl implements Blob {
     static final Logger logger = LoggerFactoryService.getFactory()
             .getInstance(BlobImpl.class);
 
-    private NdbBlob ndbBlob;
+    protected NdbBlob ndbBlob;
+
+    public BlobImpl() {
+        // this is only for NdbRecordBlobImpl constructor when there is no ndbBlob available yet
+    }
 
     public BlobImpl(NdbBlob blob) {
         this.ndbBlob = blob;

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterConnectionImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterConnectionImpl.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterConnectionImpl.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ *  Copyright (c) 2010, 2012, 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
@@ -20,13 +20,18 @@ package com.mysql.clusterj.tie;
 import java.util.IdentityHashMap;
 import java.util.Map;
 
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
 import com.mysql.ndbjtie.ndbapi.Ndb;
 import com.mysql.ndbjtie.ndbapi.Ndb_cluster_connection;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.Dictionary;
 
 import com.mysql.clusterj.ClusterJDatastoreException;
 import com.mysql.clusterj.ClusterJFatalInternalException;
 
 import com.mysql.clusterj.core.store.Db;
+import com.mysql.clusterj.core.store.Table;
 
 import com.mysql.clusterj.core.util.I18NHelper;
 import com.mysql.clusterj.core.util.Logger;
@@ -57,6 +62,12 @@ public class ClusterConnectionImpl
     /** All dbs given out by this cluster connection */
     private Map<DbImpl, Object> dbs = new IdentityHashMap<DbImpl, Object>();
 
+    /** The map of table name to NdbRecordImpl */
+    private ConcurrentMap<String, NdbRecordImpl> ndbRecordImplMap = new ConcurrentHashMap<String, NdbRecordImpl>();
+
+    /** The dictionary used to create NdbRecords */
+    Dictionary dictionaryForNdbRecord = null;
+
     /** Connect to the MySQL Cluster
      * 
      * @param connectString the connect string
@@ -83,6 +94,14 @@ public class ClusterConnectionImpl
         synchronized(this) {
             ndb = Ndb.create(clusterConnection, database, "def");
             handleError(ndb, clusterConnection, connectString, nodeId);
+            if (dictionaryForNdbRecord == null) {
+                // create a dictionary for NdbRecord
+                Ndb ndbForNdbRecord = Ndb.create(clusterConnection, database, "def");
+                handleError(ndbForNdbRecord, clusterConnection, connectString, nodeId);
+                DbImpl dbForNdbRecord = new DbImpl(this, ndbForNdbRecord, maxTransactions);
+                dbs.put(dbForNdbRecord, null);
+                dictionaryForNdbRecord = dbForNdbRecord.getNdbDictionary();
+            }
         }
         DbImpl result = new DbImpl(this, ndb, maxTransactions);
         dbs.put(result, null);
@@ -143,6 +162,16 @@ public class ClusterConnectionImpl
     public void close() {
         if (clusterConnection != null) {
             logger.info(local.message("INFO_Close_Cluster_Connection", connectString, nodeId));
+            for (NdbRecordImpl ndbRecord: ndbRecordImplMap.values()) {
+                ndbRecord.releaseNdbRecord();
+            }
+            ndbRecordImplMap.clear();
+            if (dbs.size() != 0) {
+                Map<DbImpl, Object> dbsToClose = new IdentityHashMap<DbImpl, Object>(dbs);
+                for (Db db: dbsToClose.keySet()) {
+                    db.close();
+                }
+            }
             Ndb_cluster_connection.delete(clusterConnection);
             clusterConnection = null;
         }
@@ -153,7 +182,43 @@ public class ClusterConnectionImpl
     }
 
     public int dbCount() {
-        return dbs.size();
+        // one of the dbs is for the NdbRecord dictionary if it is not null
+        int dbForNdbRecord = (dictionaryForNdbRecord == null)?0:1;
+        return dbs.size() - dbForNdbRecord;
+    }
+
+    /** 
+     * Get the cached NdbRecord implementation for this cluster connection.
+     * There are three possibilities:
+     * <ul><li>Case 1: return the already-cached NdbRecord
+     * </li><li>Case 2: return a new instance created by this method
+     * </li><li>Case 3: return the winner of a race with another thread
+     * </li></ul>
+     * @param storeTable the store table
+     * @param ndbDictionary the ndb dictionary
+     * @return the NdbRecordImpl
+     */
+    protected NdbRecordImpl getCachedNdbRecordImpl(Table storeTable) {
+        String tableName = storeTable.getName();
+        // find the NdbRecordImpl in the global cache
+        NdbRecordImpl result = ndbRecordImplMap.get(tableName);
+        if (result != null) {
+            // case 1
+            return result;
+        } else {
+            NdbRecordImpl newNdbRecordImpl = new NdbRecordImpl(storeTable, dictionaryForNdbRecord);
+            NdbRecordImpl winner = ndbRecordImplMap.putIfAbsent(tableName, newNdbRecordImpl);
+            if (winner == null) {
+                // case 2: the previous value was null, so return the new (winning) value
+                if (logger.isDebugEnabled())logger.debug("NdbRecordImpl created for " + tableName);
+                return newNdbRecordImpl;
+            } else {
+                // case 3: another thread beat us, so return the winner and garbage collect ours
+                if (logger.isDebugEnabled())logger.debug("NdbRecordImpl lost race for " + tableName);
+                newNdbRecordImpl.releaseNdbRecord();
+                return winner;
+            }
+        }
     }
 
 }

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterConnectionServiceImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterConnectionServiceImpl.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterConnectionServiceImpl.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ *  Copyright (c) 2010, 2012, 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
@@ -22,6 +22,10 @@ import com.mysql.clusterj.core.store.Clu
 import com.mysql.clusterj.core.util.I18NHelper;
 import com.mysql.clusterj.core.util.Logger;
 import com.mysql.clusterj.core.util.LoggerFactoryService;
+import com.mysql.ndbjtie.ndbapi.Ndb;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary;
+import com.mysql.ndbjtie.ndbapi.NdbOperation;
+import com.mysql.ndbjtie.ndbapi.NdbScanOperation;
 
 /**
  *
@@ -43,6 +47,18 @@ public class ClusterConnectionServiceImp
     /** Load the ndbclient system library only once */
     static boolean ndbclientLoaded = false;
 
+    /** Size of OperationOptions, needed for some ndb apis */
+    static int SIZEOF_OPERATION_OPTIONS;
+
+    /** Size of PartitionSpec, needed for some ndb apis */
+    static int SIZEOF_PARTITION_SPEC;
+
+    /** Size of RecordSpecification, needed for some ndb apis */
+    static int SIZEOF_RECORD_SPECIFICATION;
+
+    /** Size of ScanOptions, needed for some ndb apis */
+    static int SIZEOF_SCAN_OPTIONS;
+
     static protected void loadSystemLibrary(String name) {
         // this is not thread-protected so it might be executed multiple times but no matter
         if (ndbclientLoaded) {
@@ -52,6 +68,11 @@ public class ClusterConnectionServiceImp
             System.loadLibrary(name);
             // initialize the charset map
             Utility.getCharsetMap();
+            // get the size information for Ndb structs as needed by some ndb apis
+            SIZEOF_OPERATION_OPTIONS = NdbOperation.OperationOptions.size();
+            SIZEOF_PARTITION_SPEC = Ndb.PartitionSpec.size();
+            SIZEOF_RECORD_SPECIFICATION = NdbDictionary.RecordSpecification.size();
+            SIZEOF_SCAN_OPTIONS = NdbScanOperation.ScanOptions.size();
             ndbclientLoaded = true;
         } catch (Throwable e) {
             String path = getLoadLibraryPath();

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterTransactionImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterTransactionImpl.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ClusterTransactionImpl.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ *  Copyright (c) 2009, 2012, 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
@@ -17,6 +17,7 @@
 
 package com.mysql.clusterj.tie;
 
+import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -42,11 +43,14 @@ import com.mysql.ndbjtie.ndbapi.NdbError
 import com.mysql.ndbjtie.ndbapi.NdbIndexOperation;
 import com.mysql.ndbjtie.ndbapi.NdbIndexScanOperation;
 import com.mysql.ndbjtie.ndbapi.NdbOperation;
+import com.mysql.ndbjtie.ndbapi.NdbOperationConst;
+import com.mysql.ndbjtie.ndbapi.NdbRecordConst;
 import com.mysql.ndbjtie.ndbapi.NdbScanOperation;
 import com.mysql.ndbjtie.ndbapi.NdbTransaction;
 import com.mysql.ndbjtie.ndbapi.NdbDictionary.Dictionary;
 import com.mysql.ndbjtie.ndbapi.NdbDictionary.IndexConst;
 import com.mysql.ndbjtie.ndbapi.NdbDictionary.TableConst;
+import com.mysql.ndbjtie.ndbapi.NdbOperation.OperationOptionsConst;
 import com.mysql.ndbjtie.ndbapi.NdbOperationConst.AbortOption;
 import com.mysql.ndbjtie.ndbapi.NdbScanOperation.ScanFlag;
 
@@ -63,9 +67,15 @@ class ClusterTransactionImpl implements 
     static final Logger logger = LoggerFactoryService.getFactory()
             .getInstance(ClusterTransactionImpl.class);
 
+    protected final static String USE_NDBRECORD_NAME = "com.mysql.clusterj.UseNdbRecord";
+    private static boolean USE_NDBRECORD = getUseNdbRecord();
+
     protected NdbTransaction ndbTransaction;
     private List<Runnable> postExecuteCallbacks = new ArrayList<Runnable>();
 
+    /** The cluster connection for this transaction */
+    protected ClusterConnectionImpl clusterConnectionImpl;
+
     /** The DbImpl associated with this NdbTransaction */
     protected DbImpl db;
 
@@ -104,8 +114,10 @@ class ClusterTransactionImpl implements 
 
     private BufferManager bufferManager;
 
-    public ClusterTransactionImpl(DbImpl db, Dictionary ndbDictionary, String joinTransactionId) {
+    public ClusterTransactionImpl(ClusterConnectionImpl clusterConnectionImpl,
+            DbImpl db, Dictionary ndbDictionary, String joinTransactionId) {
         this.db = db;
+        this.clusterConnectionImpl = clusterConnectionImpl;
         this.ndbDictionary = ndbDictionary;
         this.joinTransactionId = joinTransactionId;
         this.bufferManager = db.getBufferManager();
@@ -209,13 +221,16 @@ class ClusterTransactionImpl implements 
 
     public Operation getInsertOperation(Table storeTable) {
         enlist();
+        if (logger.isTraceEnabled()) logger.trace("Table: " + storeTable.getName());
+        if (USE_NDBRECORD) {
+            return new NdbRecordOperationImpl(this, storeTable);
+        }
         TableConst ndbTable = ndbDictionary.getTable(storeTable.getName());
         handleError(ndbTable, ndbDictionary);
         NdbOperation ndbOperation = ndbTransaction.getNdbOperation(ndbTable);
         handleError(ndbOperation, ndbTransaction);
         int returnCode = ndbOperation.insertTuple();
         handleError(returnCode, ndbTransaction);
-        if (logger.isTraceEnabled()) logger.trace("Table: " + storeTable.getName());
         return new OperationImpl(ndbOperation, this);
     }
 
@@ -373,6 +388,22 @@ class ClusterTransactionImpl implements 
         return new OperationImpl(storeTable, ndbOperation, this);
     }
 
+    /** Create an NdbOperation for insert using NdbRecord.
+     * 
+     * @param ndbRecord the NdbRecord
+     * @param buffer the buffer with data for the operation
+     * @param mask the mask of column values already set in the buffer
+     * @param options the OperationOptions for this operation
+     * @param i 
+     * @return
+     */
+    public NdbOperationConst insertTuple(NdbRecordConst ndbRecord,
+            ByteBuffer buffer, byte[] mask, OperationOptionsConst options) {
+        NdbOperationConst operation = ndbTransaction.insertTuple(ndbRecord, buffer, mask, options, 0);
+        handleError(operation, ndbTransaction);
+        return operation;
+    }
+
     public void postExecuteCallback(Runnable callback) {
         postExecuteCallbacks.add(callback);
     }
@@ -520,4 +551,21 @@ class ClusterTransactionImpl implements 
         return bufferManager;
     }
 
+    protected NdbRecordImpl getCachedNdbRecordImpl(Table storeTable) {
+        return clusterConnectionImpl.getCachedNdbRecordImpl(storeTable);
+    }
+
+    /** Get the UseNdbRecord property from either the environment or system properties.
+     * 
+     * @return the system property if it is set via -D or the system environment
+     */
+    protected static boolean getUseNdbRecord() {
+        String useNdbRecordENV = System.getenv(USE_NDBRECORD_NAME);
+        // system property overrides environment variable
+        boolean result = System.getProperty(USE_NDBRECORD_NAME, useNdbRecordENV==null?"true":useNdbRecordENV)
+                .equals("true")?true:false;
+        logger.info("useNdbRecordENV: " + useNdbRecordENV + " UseNdbRecord: " + result);
+        return result;
+    }
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ColumnImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ColumnImpl.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/ColumnImpl.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ *  Copyright (c) 2010, 2012, 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
@@ -209,7 +209,7 @@ class ColumnImpl implements Column {
                 break;
             case ColumnConst.Type.Timestamp:
                 this.prefixLength = 0;
-                this.columnSpace = 4;
+                this.columnSpace = 0;
                 break;
             default: throw new ClusterJFatalInternalException(
                     local.message("ERR_Unknown_Column_Type",

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DbImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DbImpl.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DbImpl.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ *  Copyright (c) 2010, 2012, 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
@@ -32,7 +32,6 @@ import com.mysql.ndbjtie.ndbapi.NdbDicti
 
 import com.mysql.clusterj.ClusterJDatastoreException;
 import com.mysql.clusterj.ClusterJFatalInternalException;
-import com.mysql.clusterj.core.store.ClusterConnection;
 import com.mysql.clusterj.core.store.ClusterTransaction;
 
 import com.mysql.clusterj.core.util.I18NHelper;
@@ -82,9 +81,9 @@ class DbImpl implements com.mysql.cluste
     private DictionaryImpl dictionary;
 
     /** The ClusterConnection */
-    private ClusterConnection clusterConnection;
+    private ClusterConnectionImpl clusterConnection;
 
-    public DbImpl(ClusterConnection clusterConnection, Ndb ndb, int maxTransactions) {
+    public DbImpl(ClusterConnectionImpl clusterConnection, Ndb ndb, int maxTransactions) {
         this.clusterConnection = clusterConnection;
         this.ndb = ndb;
         int returnCode = ndb.init(maxTransactions);
@@ -103,8 +102,12 @@ class DbImpl implements com.mysql.cluste
         return dictionary;
     }
 
+    public Dictionary getNdbDictionary() {
+        return ndbDictionary;
+    }
+
     public ClusterTransaction startTransaction(String joinTransactionId) {
-        return new ClusterTransactionImpl(this, ndbDictionary, joinTransactionId);
+        return new ClusterTransactionImpl(clusterConnection, this, ndbDictionary, joinTransactionId);
     }
 
     protected void handleError(int returnCode, Ndb ndb) {

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DictionaryImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DictionaryImpl.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DictionaryImpl.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ *  Copyright (c) 2010, 2012, 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
@@ -127,4 +127,8 @@ class DictionaryImpl implements com.mysq
         ndbDictionary.removeCachedTable(tableName);
     }
 
+    public Dictionary getNdbDictionary() {
+        return ndbDictionary;
+    }
+
 }

=== added file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordBlobImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordBlobImpl.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordBlobImpl.java	revid:mikael.ronstrom@stripped
@@ -0,0 +1,56 @@
+/*
+ *  Copyright (c) 2012, 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.tie;
+
+import com.mysql.clusterj.core.store.Column;
+
+import com.mysql.clusterj.core.util.I18NHelper;
+import com.mysql.clusterj.core.util.Logger;
+import com.mysql.clusterj.core.util.LoggerFactoryService;
+
+/**
+ * NdbRecord blob handling defers the acquisition of an NdbBlob until the NdbOperation
+ * is created. At that time, this implementation will get the NdbBlob from its NdbOperation.
+ * Operations on the NdbBlob are delegated to the parent (by inheritance).
+ */
+class NdbRecordBlobImpl extends BlobImpl {
+
+    /** My message translator */
+    static final I18NHelper local = I18NHelper
+            .getInstance(NdbRecordBlobImpl.class);
+
+    /** My logger */
+    static final Logger logger = LoggerFactoryService.getFactory()
+            .getInstance(NdbRecordBlobImpl.class);
+
+    /** The store column for this blob */
+    private Column storeColumn;
+
+    /** The operation */
+    private NdbRecordOperationImpl operation;
+
+    public NdbRecordBlobImpl(NdbRecordOperationImpl operation, Column storeColumn) {
+        this.storeColumn = storeColumn;
+        this.operation = operation;
+    }
+
+    protected void setNdbBlob() {
+        this.ndbBlob = operation.getNdbBlob(storeColumn);
+    }
+
+}

=== added file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordImpl.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordImpl.java	revid:mikael.ronstrom@stripped
@@ -0,0 +1,375 @@
+/*
+   Copyright (c) 2012, 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.tie;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import java.nio.ByteBuffer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.mysql.clusterj.ClusterJFatalInternalException;
+import com.mysql.clusterj.ClusterJFatalUserException;
+
+import com.mysql.clusterj.core.store.Column;
+import com.mysql.clusterj.core.store.Table;
+import com.mysql.clusterj.core.util.I18NHelper;
+import com.mysql.clusterj.core.util.Logger;
+import com.mysql.clusterj.core.util.LoggerFactoryService;
+
+import com.mysql.clusterj.tie.DbImpl.BufferManager;
+
+import com.mysql.ndbjtie.ndbapi.NdbRecord;
+import com.mysql.ndbjtie.ndbapi.NdbRecordConst;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.ColumnConst;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.Dictionary;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.RecordSpecification;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.RecordSpecificationArray;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.TableConst;
+
+/**
+ * Wrapper around an NdbRecord. The default implementation can be used for insert,
+ * using an NdbRecord that defines every column in the table. After construction, the instance is
+ * read-only and can be shared among all threads that use the same cluster connection; and the size of the
+ * buffer required for operations is available. The NdbRecord instance is released when the cluster
+ * connection is closed. Column values can be set using a provided
+ * buffer and buffer manager.
+ */
+public class NdbRecordImpl {
+
+    /** My message translator */
+    static final I18NHelper local = I18NHelper
+            .getInstance(NdbRecordImpl.class);
+
+    /** My logger */
+    static final Logger logger = LoggerFactoryService.getFactory()
+            .getInstance(NdbRecordImpl.class);
+
+    /** The size of the NdbRecord struct */
+    protected final static int SIZEOF_RECORD_SPECIFICATION = ClusterConnectionServiceImpl.SIZEOF_RECORD_SPECIFICATION;
+
+    /** The NdbRecord for this operation */
+    private NdbRecord ndbRecord = null;
+
+    /** The store columns for this operation */
+    protected List<Column> storeColumns = new ArrayList<Column>();
+
+    /** The RecordSpecificationArray used to define the columns in the NdbRecord */
+    private RecordSpecificationArray recordSpecificationArray;
+
+    /** The NdbTable */
+    TableConst tableConst;
+
+    /** The size of the receive buffer for this operation (may be zero for non-read operations) */
+    protected int bufferSize;
+
+    /** The maximum column id for this operation (may be zero for non-read operations) */
+    protected int maximumColumnId;
+
+    /** The offsets into the buffer for each column (may be null for non-read operations) */
+    protected int[] offsets;
+
+    /** Values for setting column mask and null bit mask */
+    protected final static byte[] BIT_IN_BYTE_MASK = new byte[] {1, 2, 4, 8, 16, 32, 64, -128};
+
+    /** The position in the null indicator for the field */
+    protected int nullablePositions[] = null;
+
+    /** The null indicator for the field bit in the byte */
+    protected int nullbitBitInByte[] = null;
+
+    /** The null indicator for the field byte offset*/
+    protected int nullbitByteOffset[] = null;
+
+    /** The maximum length of any column in this operation */
+    protected int maximumColumnLength;
+
+    /** The dictionary used to create (and release) the NdbRecord */
+    private Dictionary ndbDictionary;
+
+    /** Number of columns for this NdbRecord */
+    private int numberOfColumns;
+
+    /** These fields are only used during construction of the RecordSpecificationArray */
+    int offset = 0;
+    int nullablePosition = 0;
+
+    /** Constructor used for insert operations that do not need to read data.
+     * 
+     * @param storeTable the store table
+     * @param ndbDictionary the ndb dictionary
+     */
+    protected NdbRecordImpl(Table storeTable, Dictionary ndbDictionary) {
+        this.ndbDictionary = ndbDictionary;
+        this.tableConst = getNdbTable(storeTable.getName());
+        this.numberOfColumns = tableConst.getNoOfColumns();
+        this.recordSpecificationArray = RecordSpecificationArray.create(numberOfColumns);
+        this.offsets = new int[numberOfColumns];
+        this.nullablePositions = new int[numberOfColumns];
+        this.nullbitBitInByte = new int[numberOfColumns];
+        this.nullbitByteOffset = new int[numberOfColumns];
+        this.ndbRecord = createNdbRecord(storeTable, ndbDictionary);
+    }
+
+
+    public int setBigInteger(ByteBuffer buffer, Column storeColumn, BigInteger value) {
+        int columnId = storeColumn.getColumnId();
+        int newPosition = offsets[columnId];
+        buffer.position(newPosition);
+        ByteBuffer bigIntegerBuffer = Utility.convertValue(storeColumn, value);
+        buffer.put(bigIntegerBuffer);
+        return columnId;
+    }
+
+    public int setByte(ByteBuffer buffer, Column storeColumn, byte value) {
+        int columnId = storeColumn.getColumnId();
+        buffer.put(offsets[columnId], value);
+        return columnId;
+    }
+
+    public int setBytes(ByteBuffer buffer, Column storeColumn, byte[] value) {
+        int columnId = storeColumn.getColumnId();
+        int newPosition = offsets[columnId];
+        buffer.position(newPosition);
+        Utility.convertValue(buffer, storeColumn, value);
+        return columnId;
+    }
+
+    public int setDecimal(ByteBuffer buffer, Column storeColumn, BigDecimal value) {
+        int columnId = storeColumn.getColumnId();
+        int newPosition = offsets[columnId];
+        buffer.position(newPosition);
+        ByteBuffer decimalBuffer = Utility.convertValue(storeColumn, value);
+        buffer.put(decimalBuffer);
+        return columnId;
+    }
+
+    public int setDouble(ByteBuffer buffer, Column storeColumn, Double value) {
+        int columnId = storeColumn.getColumnId();
+        buffer.putDouble(offsets[columnId], value);
+        return columnId;
+    }
+
+    public int setFloat(ByteBuffer buffer, Column storeColumn, Float value) {
+        int columnId = storeColumn.getColumnId();
+        buffer.putFloat(offsets[columnId], value);
+        return columnId;
+    }
+
+    public int setInt(ByteBuffer buffer, Column storeColumn, Integer value) {
+        int columnId = storeColumn.getColumnId();
+        buffer.putInt(offsets[columnId], value);
+        return columnId;
+    }
+
+    public int setLong(ByteBuffer buffer, Column storeColumn, long value) {
+        int columnId = storeColumn.getColumnId();
+        long storeValue = Utility.convertLongValueForStorage(storeColumn, value);
+        buffer.putLong(offsets[columnId], storeValue);
+        return columnId;
+    }
+
+    public int setNull(ByteBuffer buffer, Column storeColumn) {
+        int columnId = storeColumn.getColumnId();
+        int index = nullbitByteOffset[columnId];
+        byte mask = BIT_IN_BYTE_MASK[nullbitBitInByte[columnId]];
+        byte nullbyte = buffer.get(index);
+        buffer.put(index, (byte)(nullbyte|mask));
+        return columnId;
+    }
+
+    public int setShort(ByteBuffer buffer, Column storeColumn, Short value) {
+        int columnId = storeColumn.getColumnId();
+        buffer.putShort(offsets[columnId], value);
+        return columnId;
+    }
+
+    public int setString(ByteBuffer buffer, BufferManager bufferManager, Column storeColumn, String value) {
+        int columnId = storeColumn.getColumnId();
+        buffer.position(offsets[columnId]);
+        // for now, use the encode method to encode the value then copy it
+        ByteBuffer converted = Utility.encode(value, storeColumn, bufferManager);
+        buffer.put(converted);
+        return columnId;
+    }
+
+    protected static void handleError(Object object, Dictionary ndbDictionary) {
+        if (object != null) {
+            return;
+        } else {
+            Utility.throwError(null, ndbDictionary.getNdbError());
+        }
+    }
+
+    protected NdbRecord createNdbRecord(Table storeTable, Dictionary ndbDictionary) {
+        String[] columnNames = storeTable.getColumnNames();
+        List<Column> align8 = new ArrayList<Column>();
+        List<Column> align4 = new ArrayList<Column>();
+        List<Column> align2 = new ArrayList<Column>();
+        List<Column> align1 = new ArrayList<Column>();
+        List<Column> nullables = new ArrayList<Column>();
+        for (String columnName: columnNames) {
+            Column storeColumn = storeTable.getColumn(columnName);
+            storeColumns.add(storeColumn);
+            // for each column, put into alignment bucket
+            switch (storeColumn.getType()) {
+                case Bigint:
+                case Bigunsigned:
+                case Bit:
+                case Blob:
+                case Date:
+                case Datetime:
+                case Double:
+                case Text:
+                case Time:
+                case Timestamp:
+                    align8.add(storeColumn);
+                    break;
+                case Binary:
+                case Char:
+                case Decimal:
+                case Decimalunsigned:
+                case Longvarbinary:
+                case Longvarchar:
+                case Olddecimal:
+                case Olddecimalunsigned:
+                case Tinyint:
+                case Tinyunsigned:
+                case Varbinary:
+                case Varchar:
+                    align1.add(storeColumn);
+                    break;
+                case Float:
+                case Int:
+                case Mediumint:
+                case Mediumunsigned:
+                case Unsigned:
+                    align4.add(storeColumn);
+                    break;
+                case Smallint:
+                case Smallunsigned:
+                case Year:
+                    align2.add(storeColumn);
+                    break;
+                case Undefined:
+                    throw new ClusterJFatalUserException(local.message("ERR_Unknown_Column_Type",
+                            storeTable.getName(), columnName, storeColumn.getType()));
+                default:
+                    throw new ClusterJFatalInternalException(local.message("ERR_Unknown_Column_Type",
+                            storeTable.getName(), columnName, storeColumn.getType()));
+            }
+            if (storeColumn.getNullable()) {
+                nullables.add(storeColumn);
+            }
+        }
+        // for each column, allocate space in the buffer, starting with align8 and ending with align1
+        // null indicators are allocated first, with one bit per nullable column
+        // nullable columns take one bit each
+        offset = nullables.size() + 7 / 8;
+        // align the first column following the nullable column indicators to 8
+        offset = (7 + offset) / 8 * 8;
+        for (Column storeColumn: align8) {
+            handleColumn(8, storeColumn);
+        }
+        for (Column storeColumn: align4) {
+            handleColumn(4, storeColumn);
+        }
+        for (Column storeColumn: align2) {
+            handleColumn(2, storeColumn);
+        }
+        for (Column storeColumn: align1) {
+            handleColumn(1, storeColumn);
+        }
+        bufferSize = offset;
+
+        // now create an NdbRecord
+        NdbRecord result = ndbDictionary.createRecord(tableConst, recordSpecificationArray,
+                numberOfColumns, SIZEOF_RECORD_SPECIFICATION, 0);
+        // delete the RecordSpecificationArray since it is no longer needed
+        RecordSpecificationArray.delete(recordSpecificationArray);
+        handleError(result, ndbDictionary);
+        return result;
+    }
+
+    /** Create a record specification for a column. Keep track of the offset into the buffer
+     * and the null indicator position for each column.
+     * 
+     * @param alignment the alignment for this column in the buffer
+     * @param storeColumn the column
+     */
+    private void handleColumn(int alignment, Column storeColumn) {
+        int columnId = storeColumn.getColumnId();
+        RecordSpecification recordSpecification = recordSpecificationArray.at(columnId);
+        ColumnConst columnConst = tableConst.getColumn(columnId);
+        recordSpecification.column(columnConst);
+        recordSpecification.offset(offset);
+        offsets[columnId] = offset;
+        int columnSpace = storeColumn.getColumnSpace();
+        offset += (columnSpace==0)?8:columnSpace;
+        if (storeColumn.getNullable()) {
+            nullablePositions[columnId] = nullablePosition++;
+            int nullbitByteOffsetValue = nullablePosition/8;
+            int nullbitBitInByteValue = nullablePosition - nullablePosition / 8 * 8;
+            nullbitBitInByte[columnId] = nullbitBitInByteValue;
+            nullbitByteOffset[columnId] = nullbitByteOffsetValue;
+            recordSpecification.nullbit_byte_offset(nullbitByteOffsetValue);
+            recordSpecification.nullbit_bit_in_byte(nullbitBitInByteValue);
+        } else {
+            recordSpecification.nullbit_byte_offset(0);
+            recordSpecification.nullbit_bit_in_byte(0);
+        }
+        if (logger.isDetailEnabled()) logger.detail(
+                "column: " + storeColumn.getName()
+                + " columnSpace: " + columnSpace 
+                + " offset: " + offsets[columnId]
+                + " nullable position: " + nullablePositions[columnId]
+                + " nullbitByteOffset: " + nullbitByteOffset[columnId]
+                + " nullbitBitInByte: " +  nullbitBitInByte[columnId]);
+    }
+
+    TableConst getNdbTable(String tableName) {
+        TableConst ndbTable = ndbDictionary.getTable(tableName);
+        if (ndbTable == null) {
+            // try the lower case table name
+            ndbTable = ndbDictionary.getTable(tableName.toLowerCase());
+        }
+        return ndbTable;
+    }
+
+    public int getBufferSize() {
+        return bufferSize;
+    }
+
+    public NdbRecordConst getNdbRecord() {
+        return ndbRecord;
+    }
+
+    public int getNumberOfColumns() {
+        return numberOfColumns;
+    }
+
+    protected void releaseNdbRecord() {
+        if (ndbRecord != null) {
+            ndbDictionary.releaseRecord(ndbRecord);
+            ndbRecord = null;
+        }
+    }
+
+}

=== added file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordOperationImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordOperationImpl.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordOperationImpl.java	revid:mikael.ronstrom@stripped
@@ -0,0 +1,318 @@
+/*
+   Copyright (c) 2012, 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.tie;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.mysql.clusterj.ClusterJFatalInternalException;
+
+import com.mysql.clusterj.core.store.Blob;
+import com.mysql.clusterj.core.store.Column;
+import com.mysql.clusterj.core.store.Operation;
+import com.mysql.clusterj.core.store.ResultData;
+import com.mysql.clusterj.core.store.Table;
+import com.mysql.clusterj.core.util.I18NHelper;
+import com.mysql.clusterj.core.util.Logger;
+import com.mysql.clusterj.core.util.LoggerFactoryService;
+
+import com.mysql.clusterj.tie.DbImpl.BufferManager;
+
+import com.mysql.ndbjtie.ndbapi.NdbBlob;
+import com.mysql.ndbjtie.ndbapi.NdbOperationConst;
+import com.mysql.ndbjtie.ndbapi.NdbDictionary.Dictionary;
+
+/**
+ * Implementation of store operation that uses NdbRecord.
+ */
+class NdbRecordOperationImpl implements Operation {
+
+    /** My message translator */
+    static final I18NHelper local = I18NHelper
+            .getInstance(NdbRecordOperationImpl.class);
+
+    /** My logger */
+    static final Logger logger = LoggerFactoryService.getFactory()
+            .getInstance(NdbRecordOperationImpl.class);
+
+    /** The ClusterTransaction that this operation belongs to */
+    protected ClusterTransactionImpl clusterTransaction;
+
+    /** The NdbOperation wrapped by this object */
+    private NdbOperationConst ndbOperation = null;
+
+    /** The NdbRecord for this operation */
+    private NdbRecordImpl ndbRecordImpl = null;
+
+    /** The mask for this operation, which contains a bit set for each column to be inserted */
+    byte[] mask;
+
+    /** The ByteBuffer containing all of the data */
+    ByteBuffer buffer = null;
+
+    /** Blobs for this NdbRecord */
+    protected NdbRecordBlobImpl[] blobs = null;
+
+    /** Blobs that have been accessed for this operation */
+    protected List<NdbRecordBlobImpl> activeBlobs = new ArrayList<NdbRecordBlobImpl>();
+
+    /** The size of the receive buffer for this operation (may be zero for non-read operations) */
+    protected int bufferSize;
+
+    /** The number of columns for this operation */
+    protected int numberOfColumns;
+
+    protected BufferManager bufferManager;
+
+    /** Constructor used for insert and delete operations that do not need to read data.
+     * 
+     * @param clusterTransaction the cluster transaction
+     * @param transaction the ndb transaction
+     * @param storeTable the store table
+     */
+    public NdbRecordOperationImpl(ClusterTransactionImpl clusterTransaction, Table storeTable) {
+        this.ndbRecordImpl = clusterTransaction.getCachedNdbRecordImpl(storeTable);
+        this.bufferSize = ndbRecordImpl.getBufferSize();
+        this.numberOfColumns = ndbRecordImpl.getNumberOfColumns();
+        this.blobs = new NdbRecordBlobImpl[this.numberOfColumns];
+        this.clusterTransaction = clusterTransaction;
+        this.bufferManager = clusterTransaction.getBufferManager();
+    }
+
+    public void equalBigInteger(Column storeColumn, BigInteger value) {
+        setBigInteger(storeColumn, value);
+    }
+
+    public void equalBoolean(Column storeColumn, boolean booleanValue) {
+        setBoolean(storeColumn, booleanValue);
+    }
+
+    public void equalByte(Column storeColumn, byte value) {
+        setByte(storeColumn, value);
+    }
+
+    public void equalBytes(Column storeColumn, byte[] value) {
+        setBytes(storeColumn, value);
+   }
+
+    public void equalDecimal(Column storeColumn, BigDecimal value) {
+        setDecimal(storeColumn, value);
+    }
+
+    public void equalDouble(Column storeColumn, double value) {
+        setDouble(storeColumn, value);
+    }
+
+    public void equalFloat(Column storeColumn, float value) {
+        setFloat(storeColumn, value);
+    }
+
+    public void equalInt(Column storeColumn, int value) {
+        setInt(storeColumn, value);
+    }
+
+    public void equalShort(Column storeColumn, short value) {
+        setShort(storeColumn, value);
+    }
+
+    public void equalLong(Column storeColumn, long value) {
+        setLong(storeColumn, value);
+    }
+
+    public void equalString(Column storeColumn, String value) {
+        setString(storeColumn, value);
+    }
+
+    public void getBlob(Column storeColumn) {
+        throw new ClusterJFatalInternalException(local.message("ERR_Method_Not_Implemented", "getBlob"));
+    }
+
+    /**
+     * Get the blob handle for this column. The same column will return the same blob handle
+     * regardless of how many times it is called.
+     * @param storeColumn the store column
+     * @return the blob handle
+     */
+    public Blob getBlobHandle(Column storeColumn) {
+        int columnId = storeColumn.getColumnId();
+        NdbRecordBlobImpl result = blobs[columnId];
+        if (result == null) {
+            columnSet(columnId);
+            result = new NdbRecordBlobImpl(this, storeColumn);
+            blobs[columnId] = result;
+            activeBlobs.add(result);
+        }
+        return result;
+    }
+
+    /** Specify the columns to be used for the operation.
+     */
+    public void getValue(Column storeColumn) {
+        throw new ClusterJFatalInternalException(local.message("ERR_Method_Not_Implemented", "getValue"));
+    }
+
+    public void postExecuteCallback(Runnable callback) {
+        clusterTransaction.postExecuteCallback(callback);
+    }
+
+    /** Construct a new ResultData using the saved column data and then execute the operation.
+     */
+    public ResultData resultData() {
+        throw new ClusterJFatalInternalException(local.message("ERR_Method_Not_Implemented", "resultData"));
+    }
+
+    /** Construct a new ResultData and if requested, execute the operation.
+     */
+    public ResultData resultData(boolean execute) {
+        throw new ClusterJFatalInternalException(local.message("ERR_Method_Not_Implemented", "resultData"));
+    }
+
+    public void setBigInteger(Column storeColumn, BigInteger value) {
+        int columnId = ndbRecordImpl.setBigInteger(buffer, storeColumn, value);
+        columnSet(columnId);
+    }
+
+    public void setBoolean(Column storeColumn, Boolean booleanValue) {
+        byte value = (booleanValue?(byte)0x01:(byte)0x00);
+        setByte(storeColumn, value);
+    }
+
+    public void setByte(Column storeColumn, byte value) {
+        int columnId = ndbRecordImpl.setByte(buffer, storeColumn, value);
+        columnSet(columnId);
+    }
+
+    public void setBytes(Column storeColumn, byte[] value) {
+        int columnId = ndbRecordImpl.setBytes(buffer, storeColumn, value);
+        columnSet(columnId);
+    }
+
+    public void setDecimal(Column storeColumn, BigDecimal value) {
+        int columnId = ndbRecordImpl.setDecimal(buffer, storeColumn, value);
+        columnSet(columnId);
+    }
+
+    public void setDouble(Column storeColumn, Double value) {
+        int columnId = ndbRecordImpl.setDouble(buffer, storeColumn, value);
+        columnSet(columnId);
+    }
+
+    public void setFloat(Column storeColumn, Float value) {
+        int columnId = ndbRecordImpl.setFloat(buffer, storeColumn, value);
+        columnSet(columnId);
+    }
+
+    public void setInt(Column storeColumn, Integer value) {
+        int columnId = ndbRecordImpl.setInt(buffer, storeColumn, value);
+        columnSet(columnId);
+    }
+
+    public void setLong(Column storeColumn, long value) {
+        int columnId = ndbRecordImpl.setLong(buffer, storeColumn, value);
+        columnSet(columnId);
+    }
+
+    public void setNull(Column storeColumn) {
+        int columnId = ndbRecordImpl.setNull(buffer, storeColumn);
+        columnSet(columnId);
+    }
+
+    public void setShort(Column storeColumn, Short value) {
+        int columnId = ndbRecordImpl.setShort(buffer, storeColumn, value);
+        columnSet(columnId);
+    }
+
+    public void setString(Column storeColumn, String value) {
+        int columnId = ndbRecordImpl.setString(buffer, bufferManager, storeColumn, value);
+        columnSet(columnId);
+    }
+
+    public int errorCode() {
+        return ndbOperation.getNdbError().code();
+    }
+
+    protected static void handleError(int returnCode, NdbOperationConst ndbOperation2) {
+        if (returnCode == 0) {
+            return;
+        } else {
+            Utility.throwError(returnCode, ndbOperation2.getNdbError());
+        }
+    }
+
+    protected static void handleError(Object object, NdbOperationConst ndbOperation) {
+        if (object != null) {
+            return;
+        } else {
+            Utility.throwError(null, ndbOperation.getNdbError());
+        }
+    }
+
+    protected static void handleError(Object object, Dictionary ndbDictionary) {
+        if (object != null) {
+            return;
+        } else {
+            Utility.throwError(null, ndbDictionary.getNdbError());
+        }
+    }
+
+    public void beginDefinition() {
+        // allocate a buffer for the operation data
+        buffer = ByteBuffer.allocateDirect(bufferSize);
+        // use platform's native byte ordering
+        buffer.order(ByteOrder.nativeOrder());
+        mask = new byte[1 + (numberOfColumns/8)];
+    }
+
+    public void endDefinition() {
+        // create the insert operation
+        buffer.position(0);
+        buffer.limit(bufferSize);
+        // create the insert operation
+        ndbOperation = clusterTransaction.insertTuple(ndbRecordImpl.getNdbRecord(), buffer, mask, null);
+        // now set the NdbBlob into the blobs
+        for (NdbRecordBlobImpl blob: activeBlobs) {
+            if (blob != null) {
+                blob.setNdbBlob();
+            }
+        }
+    }
+
+    public NdbBlob getNdbBlob(Column storeColumn) {
+        NdbBlob result = ndbOperation.getBlobHandle(storeColumn.getColumnId());
+        handleError(result, ndbOperation);
+        return result;
+    }
+
+    /**
+     * Set this column into the mask for NdbRecord operation.
+     * @param columnId the column id
+     */
+    private void columnSet(int columnId) {
+        int byteOffset = columnId / 8;
+        int bitInByte = columnId - (byteOffset * 8);
+        mask[byteOffset] |= NdbRecordImpl.BIT_IN_BYTE_MASK[bitInByte];
+        
+    }
+
+}

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2009, 2012, 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
@@ -263,7 +263,7 @@ class OperationImpl implements Operation
 
     public void setLong(Column storeColumn, long value) {
         long storeValue = Utility.convertLongValueForStorage(storeColumn, value);
-        int returnCode = ndbOperation.setValue(storeColumn.getName(), storeValue);
+        int returnCode = ndbOperation.setValue(storeColumn.getColumnId(), storeValue);
         handleError(returnCode, ndbOperation);
     }
 
@@ -305,4 +305,12 @@ class OperationImpl implements Operation
         }
     }
 
+    public void beginDefinition() {
+        // nothing to do
+    }
+
+    public void endDefinition() {
+        // nothing to do
+    }
+
 }

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/Utility.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/Utility.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/Utility.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ *  Copyright (c) 2010, 2012, 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
@@ -792,9 +792,22 @@ public class Utility {
      * @return the ByteBuffer
      */
     public static ByteBuffer convertValue(Column storeColumn, byte[] value) {
+        int requiredLength = storeColumn.getColumnSpace();
+        ByteBuffer result = ByteBuffer.allocateDirect(requiredLength);
+        convertValue(result, storeColumn, value);
+        result.flip();
+        return result;
+    }
+
+    /** Convert the parameter value and store it in a given ByteBuffer that can be passed to ndbjtie.
+     * 
+     * @param buffer the buffer, positioned at the location to store the value
+     * @param storeColumn the column definition
+     * @param value the value to be converted
+     */
+    public static void convertValue(ByteBuffer buffer, Column storeColumn, byte[] value) {
         int dataLength = value.length;
         int prefixLength = storeColumn.getPrefixLength();
-        ByteBuffer result;
         switch (prefixLength) {
             case 0:
                 int requiredLength = storeColumn.getColumnSpace();
@@ -803,12 +816,10 @@ public class Utility {
                             local.message("ERR_Data_Too_Long",
                             storeColumn.getName(), requiredLength, dataLength));
                 } else {
-                    result = ByteBuffer.allocateDirect(requiredLength);
-                    result.order(ByteOrder.nativeOrder());
-                    result.put(value);
+                    buffer.put(value);
                     if (dataLength < requiredLength) {
                         // pad with 0x00 on right
-                        result.put(ZERO_PAD, 0, requiredLength - dataLength);
+                        buffer.put(ZERO_PAD, 0, requiredLength - dataLength);
                     }
                 }
                 break;
@@ -818,10 +829,8 @@ public class Utility {
                             local.message("ERR_Data_Too_Long",
                             storeColumn.getName(), "255", dataLength));
                 }
-                result = ByteBuffer.allocateDirect(prefixLength + dataLength);
-                result.order(ByteOrder.nativeOrder());
-                result.put((byte)dataLength);
-                result.put(value);
+                buffer.put((byte)dataLength);
+                buffer.put(value);
                 break;
             case 2:
                 if (dataLength > 8000) {
@@ -829,19 +838,15 @@ public class Utility {
                             local.message("ERR_Data_Too_Long",
                             storeColumn.getName(), "8000", dataLength));
                 }
-                result = ByteBuffer.allocateDirect(prefixLength + dataLength);
-                result.order(ByteOrder.nativeOrder());
-                result.put((byte)(dataLength%256));
-                result.put((byte)(dataLength/256));
-                result.put(value);
+                buffer.put((byte)(dataLength%256));
+                buffer.put((byte)(dataLength/256));
+                buffer.put(value);
                 break;
             default: 
                     throw new ClusterJFatalInternalException(
                             local.message("ERR_Unknown_Prefix_Length",
                             prefixLength, storeColumn.getName()));
         }
-        result.flip();
-        return result;
     }
 
     /** Convert a BigDecimal value to the binary decimal form used by MySQL.

=== modified file 'storage/ndb/clusterj/clusterj-tie/src/main/resources/com/mysql/clusterj/tie/Bundle.properties'
--- a/storage/ndb/clusterj/clusterj-tie/src/main/resources/com/mysql/clusterj/tie/Bundle.properties	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/clusterj-tie/src/main/resources/com/mysql/clusterj/tie/Bundle.properties	revid:mikael.ronstrom@stripped
@@ -28,6 +28,7 @@ ERR_Cannot_Create_Cluster_Connection:Can
 ERR_Duplicate_NdbRecAttr_In_List:Duplicate NdbRecAttr for column {0} column id {1}.
 ERR_No_Operation_In_Result:There is no ndbOperation in the ResultData.
 ERR_Not_Implemented:Not implemented
+ERR_Method_Not_Implemented:Not implemented: {0}.
 ERR_NdbJTie:Error in NdbJTie: returnCode {0}, code {1}, mysqlCode {2}, \
 status {3}, classification {4}, message {5} {6}.
 ERR_Invalid_Prefix_Length:The prefix length {0} is invalid.

=== added file 'storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/StressTest.java'
--- a/storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/StressTest.java	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/clusterj/clusterj-tie/src/test/java/testsuite/clusterj/tie/StressTest.java	revid:mikael.ronstrom@stripped
@@ -0,0 +1,25 @@
+/*
+   Copyright (c) 2012, 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;
+
+import org.junit.Ignore;
+
+@Ignore
+public class StressTest extends testsuite.clusterj.StressTest {
+
+}

=== modified file 'storage/ndb/clusterj/pom.xml'
--- a/storage/ndb/clusterj/pom.xml	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/clusterj/pom.xml	revid:mikael.ronstrom@stripped
@@ -24,7 +24,7 @@
   <groupId>com.mysql.clusterj</groupId>
   <artifactId>clusterj-aggregate</artifactId>
   <packaging>pom</packaging>
-  <version>7.1.19-SNAPSHOT</version>
+  <version>7.1.20-SNAPSHOT</version>
   <name>ClusterJ Aggregate</name>
   <description>The aggregate maven project of ClusterJ</description>
   <modules>
@@ -87,32 +87,32 @@
     <dependency>
       <groupId>com.mysql.clusterj</groupId>
       <artifactId>clusterj-api</artifactId>
-      <version>7.1.19-SNAPSHOT</version>
+      <version>7.1.20-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>com.mysql.clusterj</groupId>
       <artifactId>clusterj-core</artifactId>
-      <version>7.1.19-SNAPSHOT</version>
+      <version>7.1.20-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>com.mysql.clusterj</groupId>
       <artifactId>clusterj-test</artifactId>
-      <version>7.1.19-SNAPSHOT</version>
+      <version>7.1.20-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>com.mysql.clusterj</groupId>
       <artifactId>clusterj-tie</artifactId>
-      <version>7.1.19-SNAPSHOT</version>
+      <version>7.1.20-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>com.mysql.clusterj</groupId>
       <artifactId>clusterj-jpatest</artifactId>
-      <version>7.1.19-SNAPSHOT</version>
+      <version>7.1.20-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>ndbjtie</groupId>
       <artifactId>ndbjtie</artifactId>
-      <version>7.1.19-SNAPSHOT</version>
+      <version>7.1.20-SNAPSHOT</version>
     </dependency>
     </dependencies>
   </dependencyManagement>

=== modified file 'storage/ndb/include/ndbapi/Ndb.hpp'
--- a/storage/ndb/include/ndbapi/Ndb.hpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/include/ndbapi/Ndb.hpp	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2003, 2012, 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

=== modified file 'storage/ndb/include/ndbapi/NdbDictionary.hpp'
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2003, 2012, 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

=== modified file 'storage/ndb/include/ndbapi/NdbOperation.hpp'
--- a/storage/ndb/include/ndbapi/NdbOperation.hpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/include/ndbapi/NdbOperation.hpp	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2003, 2012, 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

=== modified file 'storage/ndb/include/ndbapi/NdbScanOperation.hpp'
--- a/storage/ndb/include/ndbapi/NdbScanOperation.hpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/include/ndbapi/NdbScanOperation.hpp	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+   Copyright (c) 2003, 2012, 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

=== modified file 'storage/ndb/src/common/transporter/TransporterRegistry.cpp'
--- a/storage/ndb/src/common/transporter/TransporterRegistry.cpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/common/transporter/TransporterRegistry.cpp	revid:mikael.ronstrom@stripped
@@ -1238,7 +1238,8 @@ TransporterRegistry::poll_TCP(Uint32 tim
 
   recvdata.m_socket_poller.clear();
 
-  if (m_has_extra_wakeup_socket && recvdata.m_transporters.get(0))
+  bool extra_socket = m_has_extra_wakeup_socket;
+  if (extra_socket && recvdata.m_transporters.get(0))
   {
     const NDB_SOCKET_TYPE socket = m_extra_wakeup_sockets[0];
     assert(receiveHandle);
@@ -1271,10 +1272,13 @@ TransporterRegistry::poll_TCP(Uint32 tim
 
   if (tcpReadSelectReply > 0)
   {
-    if (m_extra_wakeup_sockets)
+    if (extra_socket)
     {
       if (recvdata.m_socket_poller.has_read(0))
+      {
+        assert(recvdata.m_transporters.get(0));
         recvdata.m_has_data_transporters.set((Uint32)0);
+      }
     }
 
     for (int i = 0; i < nTCPTransporters; i++)

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	revid:mikael.ronstrom@stripped
@@ -6536,7 +6536,8 @@ Dbdict::execADD_FRAGREQ(Signal* signal)
       findSchemaOp(op_ptr, alterTabPtr, senderData);
       ndbrequire(!op_ptr.isNull());
       alterTabPtr.p->m_dihAddFragPtr = dihPtr;
-      tabPtr = alterTabPtr.p->m_newTablePtr;
+      tabPtr.i = alterTabPtr.p->m_newTablePtrI;
+      c_tableRecordPool_.getPtr(tabPtr);
     }
     else
     {
@@ -8060,7 +8061,6 @@ Dbdict::alterTable_parse(Signal* signal,
   }
 
   // save it for abort code
-  alterTabPtr.p->m_tablePtr = tablePtr;
 
   if (tablePtr.p->tableVersion != impl_req->tableVersion) {
     jam();
@@ -8069,7 +8069,7 @@ Dbdict::alterTable_parse(Signal* signal,
   }
 
   // parse new table definition into new table record
-  TableRecordPtr& newTablePtr = alterTabPtr.p->m_newTablePtr; // ref
+  TableRecordPtr newTablePtr;
   {
     ParseDictTabInfoRecord parseRecord;
     parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
@@ -8091,6 +8091,7 @@ Dbdict::alterTable_parse(Signal* signal,
 
     // the new temporary table record seized from pool
     newTablePtr = parseRecord.tablePtr;
+    alterTabPtr.p->m_newTablePtrI = newTablePtr.i;
     alterTabPtr.p->m_newTable_realObjectId = newTablePtr.p->tableId;
     newTablePtr.p->tableId = impl_req->tableId; // set correct table id...(not the temporary)
   }
@@ -8370,7 +8371,7 @@ Dbdict::alterTable_parse(Signal* signal,
     jam();
     releaseSections(handle);
     SimplePropertiesSectionWriter w(* this);
-    packTableIntoPages(w, alterTabPtr.p->m_newTablePtr);
+    packTableIntoPages(w, newTablePtr);
 
     SegmentedSectionPtr tabInfoPtr;
     w.getPtr(tabInfoPtr);
@@ -9178,8 +9179,11 @@ Dbdict::alterTable_toLocal(Signal* signa
     {
       jam();
       HashMapRecordPtr hm_ptr;
+      TableRecordPtr newTablePtr;
+      newTablePtr.i = alterTabPtr.p->m_newTablePtrI;
+      c_tableRecordPool_.getPtr(newTablePtr);
       ndbrequire(find_object(hm_ptr,
-                                      alterTabPtr.p->m_newTablePtr.p->hashMapObjectId));
+                             newTablePtr.p->hashMapObjectId));
       req->new_map_ptr_i = hm_ptr.p->m_map_ptr_i;
     }
 
@@ -9267,7 +9271,9 @@ Dbdict::alterTable_commit(Signal* signal
     tablePtr.p->tableVersion = impl_req->newTableVersion;
     tablePtr.p->gciTableCreated = impl_req->gci;
 
-    TableRecordPtr newTablePtr = alterTabPtr.p->m_newTablePtr;
+    TableRecordPtr newTablePtr;
+    newTablePtr.i = alterTabPtr.p->m_newTablePtrI;
+    c_tableRecordPool_.getPtr(newTablePtr);
 
     const Uint32 changeMask = impl_req->changeMask;
 
@@ -9359,7 +9365,9 @@ Dbdict::alterTable_commit(Signal* signal
     /**
      * DIH is next op
      */
-    TableRecordPtr newTablePtr = alterTabPtr.p->m_newTablePtr;
+    TableRecordPtr newTablePtr;
+    newTablePtr.i = alterTabPtr.p->m_newTablePtrI;
+    c_tableRecordPool_.getPtr(newTablePtr);
     tablePtr.p->hashMapObjectId = newTablePtr.p->hashMapObjectId;
     tablePtr.p->hashMapVersion = newTablePtr.p->hashMapVersion;
     alterTabPtr.p->m_blockNo[1] = RNIL;
@@ -9575,7 +9583,7 @@ Dbdict::alterTable_fromCommitComplete(Si
     objEntry->m_transId = 0;
   }
 
-  releaseTableObject(alterTabPtr.p->m_newTablePtr.i, false);
+  releaseTableObject(alterTabPtr.p->m_newTablePtrI, false);
   sendTransConf(signal, op_ptr);
 }
 
@@ -9653,8 +9661,7 @@ Dbdict::alterTable_abortParse(Signal* si
     return;
   }
 
-  TableRecordPtr& newTablePtr = alterTabPtr.p->m_newTablePtr; // ref
-  if (!newTablePtr.isNull()) {
+  if (alterTabPtr.p->m_newTablePtrI != RNIL) {
     jam();
     // release the temporary work table
 
@@ -9667,14 +9674,8 @@ Dbdict::alterTable_abortParse(Signal* si
       objEntry->m_transId = 0;
     }
 
-    releaseTableObject(newTablePtr.i, false);
-    newTablePtr.setNull();
-  }
-
-  TableRecordPtr& tablePtr = alterTabPtr.p->m_tablePtr; // ref
-  if (!tablePtr.isNull()) {
-    jam();
-    tablePtr.setNull();
+    releaseTableObject(alterTabPtr.p->m_newTablePtrI, false);
+    alterTabPtr.p->m_newTablePtrI = RNIL;
   }
 
   sendTransConf(signal, op_ptr);

=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	revid:mikael.ronstrom@stripped
@@ -2530,8 +2530,7 @@ private:
     MutexHandle2<BACKUP_DEFINE_MUTEX> m_define_backup_mutex;
 
     // current and new temporary work table
-    TableRecordPtr m_tablePtr;
-    TableRecordPtr m_newTablePtr;
+    TableRecordPtr::I m_newTablePtrI;
     Uint32 m_newTable_realObjectId;
 
     // before image
@@ -2560,8 +2559,7 @@ private:
     AlterTableRec() :
       OpRec(g_opInfo, (Uint32*)&m_request) {
       memset(&m_request, 0, sizeof(m_request));
-      m_tablePtr.setNull();
-      m_newTablePtr.setNull();
+      m_newTablePtrI = RNIL;
       m_dihAddFragPtr = RNIL;
       m_lqhFragPtr = RNIL;
       m_blockNo[0] = DBLQH;

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/kernel/blocks/dbtup/tuppage.hpp	revid:mikael.ronstrom@stripped
@@ -63,8 +63,14 @@ struct Tup_fixsize_page
   struct File_formats::Page_header m_page_header;
   Uint32 m_restart_seq;
   Uint32 page_state;
-  Uint32 next_page;
-  Uint32 prev_page;
+  union {
+    Uint32 next_page;
+    Uint32 nextList;
+  };
+  union {
+    Uint32 prev_page;
+    Uint32 prevList;
+  };
   Uint32 first_cluster_page;
   Uint32 last_cluster_page;
   Uint32 next_cluster_page;
@@ -108,8 +114,14 @@ struct Tup_varsize_page
   struct File_formats::Page_header m_page_header;
   Uint32 m_restart_seq;
   Uint32 page_state;
-  Uint32 next_page;
-  Uint32 prev_page;
+  union {
+    Uint32 next_page;
+    Uint32 nextList;
+  };
+  union {
+    Uint32 prev_page;
+    Uint32 prevList;
+  };
   Uint32 first_cluster_page;
   Uint32 last_cluster_page;
   Uint32 next_cluster_page;

=== modified file 'storage/ndb/src/kernel/vm/CMakeLists.txt'
--- a/storage/ndb/src/kernel/vm/CMakeLists.txt	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/kernel/vm/CMakeLists.txt	revid:mikael.ronstrom@stripped
@@ -62,18 +62,19 @@ IF(NDB_BUILD_NDBMTD)
     dummy_mt.cpp)
 ENDIF()
 
+ADD_CONVENIENCE_LIBRARY(ndbtest
+    test_context.cpp
+    ../blocks/dbtup/tuppage.cpp
+)
+
 ADD_EXECUTABLE(mt_thr_config-t mt_thr_config.cpp)
 SET_TARGET_PROPERTIES(mt_thr_config-t
                       PROPERTIES COMPILE_FLAGS "-DTEST_MT_THR_CONFIG")
 TARGET_LINK_LIBRARIES(mt_thr_config-t ndbgeneral)
 
-ADD_EXECUTABLE(DynArr256-t DynArr256.cpp test_context.cpp)
-SET_TARGET_PROPERTIES(DynArr256-t
-                      PROPERTIES COMPILE_FLAGS "-DTAP_TEST")
-TARGET_LINK_LIBRARIES(DynArr256-t ndbkernel ndbsched ndberror
-                      ndbtransport
-		      ndbmgmcommon
-                      ndbmgmapi 
-                      ndbportlib
-		      ndbgeneral)
-
+FOREACH(testprog IN ITEMS CountingPool DynArr256)
+  ADD_EXECUTABLE(${testprog}-t ${testprog}.cpp)
+  SET_TARGET_PROPERTIES(${testprog}-t PROPERTIES COMPILE_FLAGS "-DTAP_TEST")
+  TARGET_LINK_LIBRARIES(${testprog}-t ndbtest ndbkernel ndbsched ndberror
+                ndbtransport ndbmgmcommon ndbmgmapi ndbportlib ndbgeneral)
+ENDFOREACH(testprog)

=== added file 'storage/ndb/src/kernel/vm/CountingPool.cpp'
--- a/storage/ndb/src/kernel/vm/CountingPool.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/kernel/vm/CountingPool.cpp	revid:mikael.ronstrom@stripped
@@ -0,0 +1,30 @@
+#ifdef TAP_TEST
+
+#include <ndb_global.h>
+#include <NdbTap.hpp>
+#include "CountingPool.hpp"
+#include "Pool.hpp"
+#include "RWPool.hpp"
+#include "test_context.hpp"
+#include "WOPool.hpp"
+
+struct record
+{
+  int dummy;
+};
+
+template class CountingPool<record, RecordPool<record, RWPool> >;
+template class CountingPool<record, RecordPool<record, WOPool> >;
+
+TAPTEST(CountingPool)
+{
+  Pool_context pc = test_context(100);
+
+  // Only compile test. See template instantiations above.
+
+  OK(true);
+
+  return 1;
+}
+
+#endif

=== added file 'storage/ndb/src/kernel/vm/CountingPool.hpp'
--- a/storage/ndb/src/kernel/vm/CountingPool.hpp	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/src/kernel/vm/CountingPool.hpp	revid:mikael.ronstrom@stripped
@@ -0,0 +1,118 @@
+#ifndef COUNTINGPOOL_HPP
+#define COUNTINGPOOL_HPP
+
+#include <ndb_global.h>
+#include "blocks/diskpage.hpp"
+#include "blocks/dbtup/tuppage.hpp"
+#include "ndbd_malloc_impl.hpp"
+#include "DLList.hpp"
+#include "Pool.hpp"
+
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+// Implementation CountingPool
+
+template<typename T, class P>
+class CountingPool : public P
+{
+  Uint32 m_inuse;
+  Uint32 m_inuse_high;
+  Uint32 m_max_allowed;
+protected:
+public:
+  CountingPool() :m_inuse(0), m_inuse_high(0), m_max_allowed(UINT32_MAX)
+    {}
+
+  bool seize(Ptr<T>& ptr)
+  {
+    if (m_inuse >= m_max_allowed)
+    {
+      return false;
+    }
+    bool ok = P::seize(ptr);
+    if (!ok)
+    {
+      return false;
+    }
+    m_inuse++;
+    if (m_inuse_high < m_inuse)
+    {
+      m_inuse_high++;
+    }
+    return true;
+  }
+
+  void release(Ptr<T> ptr)
+  {
+    P::release(ptr);
+    m_inuse--;
+  }
+
+  void release(Uint32 i)
+  {
+    Ptr<T> p;
+    getPtr(p, i);
+    release(p);
+  }
+
+  T* getPtr(Uint32 i)
+  {
+    return P::getPtr(i);
+  }
+
+  void getPtr(Ptr<T>& p, Uint32 i)
+  {
+    p.i = i;
+    p.p = getPtr(i);
+  }
+
+  void getPtr(Ptr<T>& p)
+  {
+    p.p = getPtr(p.i);
+  }
+
+  bool seize(Uint32& i)
+  {
+    Ptr<T> p;
+    p.i = i;
+    bool ok = seize(p);
+    i = p.i;
+    return ok;
+  }
+
+public:
+  // Extra methods
+  void setSize(Uint32 size)
+  {
+    m_max_allowed = size;
+  }
+
+  Uint32 getSize() const
+  {
+    return m_max_allowed /*m_seized*/;
+  }
+
+  Uint32 getEntrySize() const
+  {
+    return 8 * ((sizeof(T) + 7) / 8);  // Assuming alignment every 8 byte
+  }
+
+  Uint32 getNoOfFree() const
+  {
+    return getSize() - getUsed();
+  }
+
+  Uint32 getUsed() const
+  {
+    return m_inuse;
+  }
+
+  Uint32 getUsedHi() const
+  {
+    return m_inuse_high;
+  }
+};
+
+#endif

=== modified file 'storage/ndb/src/kernel/vm/Pool.cpp'
--- a/storage/ndb/src/kernel/vm/Pool.cpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/kernel/vm/Pool.cpp	revid:mikael.ronstrom@stripped
@@ -34,13 +34,13 @@ Pool_context::release_page(Uint32 type_i
 }
 
 void*
-Pool_context::get_memroot()
+Pool_context::get_memroot() const
 {
   return m_block->m_ctx.m_mm.get_memroot();
 }
 
 void
-Pool_context::handleAbort(int err, const char * msg)
+Pool_context::handleAbort(int err, const char * msg) const
 {
   m_block->progError(__LINE__, err, msg);
 }

=== modified file 'storage/ndb/src/kernel/vm/Pool.hpp'
--- a/storage/ndb/src/kernel/vm/Pool.hpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/kernel/vm/Pool.hpp	revid:mikael.ronstrom@stripped
@@ -72,7 +72,7 @@ struct Pool_context
   /**
    * Get mem root
    */
-  void* get_memroot();
+  void* get_memroot() const;
   
   /**
    * Alloc consekutive pages
@@ -118,12 +118,13 @@ struct Pool_context
   /**
    * Abort
    */
-  void handleAbort(int code, const char* msg) ATTRIBUTE_NORETURN;
+  void handleAbort(int code, const char* msg) const ATTRIBUTE_NORETURN;
 };
 
 template <typename T>
 struct Ptr 
 {
+  typedef Uint32 I;
   T * p;
   Uint32 i;
   inline bool isNull() const { return i == RNIL; }

=== modified file 'storage/ndb/src/ndbjtie/NdbApiWrapper.hpp'
--- a/storage/ndb/src/ndbjtie/NdbApiWrapper.hpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/ndbjtie/NdbApiWrapper.hpp	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
- Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010, 2012, 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
@@ -1415,6 +1415,13 @@ struct NdbApiWrapper {
 
 // mapped by "com_mysql_ndbjtie_ndbapi_NdbDictionary_RecordSpecification.h"
 
+    static Uint32
+    NdbDictionary__RecordSpecification__size
+    ( )
+    {
+        return NdbDictionary::RecordSpecification::size();
+    }
+
 // ---------------------------------------------------------------------------
 
 // mapped by "com_mysql_ndbjtie_ndbapi_NdbDictionary_Table.h"
@@ -2847,6 +2854,13 @@ struct NdbApiWrapper {
 
 // mapped by "com_mysql_ndbjtie_ndbapi_NdbOperation_OperationOptions.h"
 
+    static Uint32
+    NdbOperation__OperationOptions__size
+    ( )
+    {
+        return NdbOperation::OperationOptions::size();
+    }
+
 // ---------------------------------------------------------------------------
 
 // mapped by "com_mysql_ndbjtie_ndbapi_NdbOperation_SetValueSpec.h"
@@ -3252,6 +3266,13 @@ struct NdbApiWrapper {
 
 // mapped by "com_mysql_ndbjtie_ndbapi_NdbScanOperation_ScanOptions.h"
 
+    static Uint32
+    NdbScanOperation__ScanOptions__size
+    ( )
+    {
+        return NdbScanOperation::ScanOptions::size();
+    }
+
 // ---------------------------------------------------------------------------
 
 // mapped by "com_mysql_ndbjtie_ndbapi_NdbTransaction.h"
@@ -3430,6 +3451,17 @@ struct NdbApiWrapper {
 
 // ---------------------------------------------------------------------------
 
+// mapped by "com_mysql_ndbjtie_ndbapi_Ndb_PartitionSpec.h"
+
+    static Uint32
+    Ndb__PartitionSpec__size
+    ( )
+    {
+        return Ndb::PartitionSpec::size();
+    }
+
+// ---------------------------------------------------------------------------
+
 // mapped by "com_mysql_ndbjtie_ndbapi_Ndb_cluster_connection.h"
 
     static int

=== modified file 'storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/Ndb.java'
--- a/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/Ndb.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/Ndb.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+  Copyright (c) 2010, 2012, 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
@@ -48,7 +48,7 @@ public class Ndb extends Wrapper impleme
     static public interface Key_part_ptrConstArray extends ArrayWrapper< Key_part_ptrConst >
     {
     }
-    static public class Key_part_ptrArray extends Wrapper implements Key_part_ptrConstArray 
+    static public class Key_part_ptrArray extends Wrapper implements Key_part_ptrConstArray
     {
         static public native Key_part_ptrArray create(int length);
         static public native void delete(Key_part_ptrArray e);
@@ -68,6 +68,39 @@ public class Ndb extends Wrapper impleme
         static public final native Key_part_ptr create();
         static public final native void delete(Key_part_ptr p0);
     }
+    public interface /*_struct_*/ PartitionSpecConst
+    {
+        public interface /*_enum_*/ SpecType
+        {
+            int PS_NONE = 0,
+                PS_USER_DEFINED = 1,
+                PS_DISTR_KEY_PART_PTR = 2,
+                PS_DISTR_KEY_RECORD = 3;
+        }
+        int/*_SpecType_*/ type() /*_const_*/;
+    }
+    static public class /*_struct_*/ PartitionSpec extends Wrapper implements PartitionSpecConst
+    {
+        static public final native int/*_Uint32_*/ size();
+        public final native int/*_SpecType_*/ type() /*_const_*/;
+        // MMM! support mapping <union> or check if needed
+        //union {
+        //    struct {
+        //        Uint32 partitionId;
+        //    } UserDefined;
+        //    struct {
+        //        const Key_part_ptr* tableKeyParts;
+        //        void* xfrmbuf;
+        //        Uint32 xfrmbuflen;
+        //    } KeyPartPtr;
+        //    struct {
+        //        const NdbRecord* keyRecord;
+        //        const char* keyRow;
+        //        void* xfrmbuf;
+        //        Uint32 xfrmbuflen;
+        //    } KeyRecord;
+        //};
+    }
     public final native NdbTransaction/*_NdbTransaction *_*/ startTransaction(NdbDictionary.TableConst/*_const NdbDictionary.Table *_*/ table, Key_part_ptrConstArray/*_const Key_part_ptr *_*/ keyData, ByteBuffer/*_void *_*/ xfrmbuf /*_= 0_*/, int/*_Uint32_*/ xfrmbuflen /*_= 0_*/);
     public final native NdbTransaction/*_NdbTransaction *_*/ startTransaction(NdbDictionary.TableConst/*_const NdbDictionary.Table *_*/ table, int/*_Uint32_*/ partitionId);
     static public final native int computeHash(int[]/*_Uint32 *_*/ hashvalueptr, NdbDictionary.TableConst/*_const NdbDictionary.Table *_*/ p0, Key_part_ptrConstArray/*_const Key_part_ptr *_*/ keyData, ByteBuffer/*_void *_*/ xfrmbuf /*_= 0_*/, int/*_Uint32_*/ xfrmbuflen /*_= 0_*/);

=== modified file 'storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbDictionary.java'
--- a/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbDictionary.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbDictionary.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+  Copyright (c) 2010, 2012, 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
@@ -462,7 +462,7 @@ public class NdbDictionary extends Wrapp
     static public interface RecordSpecificationConstArray extends ArrayWrapper< RecordSpecificationConst >
     {
     }
-    static public class RecordSpecificationArray extends Wrapper implements RecordSpecificationConstArray 
+    static public class RecordSpecificationArray extends Wrapper implements RecordSpecificationConstArray
     {
         static public native RecordSpecificationArray create(int length);
         static public native void delete(RecordSpecificationArray e);
@@ -477,6 +477,7 @@ public class NdbDictionary extends Wrapp
     }
     static public class /*_struct_*/ RecordSpecification extends Wrapper implements RecordSpecificationConst
     {
+        static public final native int/*_Uint32_*/ size();
         public final native ColumnConst/*_const Column *_*/ column();
         public final native int/*_Uint32_*/ offset();
         public final native int/*_Uint32_*/ nullbit_byte_offset();
@@ -655,7 +656,7 @@ public class NdbDictionary extends Wrapp
             static public interface ElementConstArray extends ArrayWrapper< ElementConst >
             {
             }
-            static public class ElementArray extends Wrapper implements ElementConstArray 
+            static public class ElementArray extends Wrapper implements ElementConstArray
             {
                 static public native ElementArray create(int length);
                 static public native void delete(ElementArray e);

=== modified file 'storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbOperation.java'
--- a/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbOperation.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbOperation.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+  Copyright (c) 2010, 2012, 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
@@ -75,7 +75,7 @@ public class NdbOperation extends Wrappe
     static public interface GetValueSpecConstArray extends ArrayWrapper< GetValueSpecConst >
     {
     }
-    static public class GetValueSpecArray extends Wrapper implements GetValueSpecConstArray 
+    static public class GetValueSpecArray extends Wrapper implements GetValueSpecConstArray
     {
         static public native GetValueSpecArray create(int length);
         static public native void delete(GetValueSpecArray e);
@@ -95,7 +95,7 @@ public class NdbOperation extends Wrappe
     static public interface SetValueSpecConstArray extends ArrayWrapper< SetValueSpecConst >
     {
     }
-    static public class SetValueSpecArray extends Wrapper implements SetValueSpecConstArray 
+    static public class SetValueSpecArray extends Wrapper implements SetValueSpecConstArray
     {
         static public native SetValueSpecArray create(int length);
         static public native void delete(SetValueSpecArray e);
@@ -140,6 +140,7 @@ public class NdbOperation extends Wrappe
     }
     static public class /*_struct_*/ OperationOptions extends Wrapper implements OperationOptionsConst
     {
+        static public final native int/*_Uint32_*/ size();
         public final native long/*_Uint64_*/ optionsPresent();
         public final native int/*_AbortOption_*/ abortOption();
         public final native GetValueSpecArray/*_GetValueSpec *_*/ extraGetValues();

=== modified file 'storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbOperationConst.java'
--- a/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbOperationConst.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbOperationConst.java	revid:mikael.ronstrom@stripped
@@ -1,6 +1,5 @@
 /*
-  Copyright 2010 Sun Microsystems, Inc.
-  All rights reserved. Use is subject to license terms.
+  Copyright (c) 2010, 2012, 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
@@ -54,7 +53,7 @@ public interface NdbOperationConst
     int getNdbErrorLine() /*_const_*/;
     String/*_const char *_*/ getTableName() /*_const_*/;
     NdbDictionary.TableConst/*_const NdbDictionary.Table *_*/ getTable() /*_const_*/;
-    int/*_const Type_*/ getType() /*_const_*/;
+    int/*_Type_*/ getType() /*_const_*/;
     int/*_LockMode_*/ getLockMode() /*_const_*/;
     int/*_AbortOption_*/ getAbortOption() /*_const_*/;
     /*_virtual_*/ NdbTransaction/*_NdbTransaction *_*/ getNdbTransaction() /*_const_*/;

=== modified file 'storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbScanOperation.java'
--- a/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbScanOperation.java	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/NdbScanOperation.java	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
-  Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+  Copyright (c) 2010, 2012, 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
@@ -62,6 +62,7 @@ public class NdbScanOperation extends Nd
     }
     static public class /*_struct_*/ ScanOptions extends Wrapper implements ScanOptionsConst
     {
+        static public final native int/*_Uint32_*/ size();
         public final native long/*_Uint64_*/ optionsPresent();
         public final native int/*_Uint32_*/ scan_flags();
         public final native int/*_Uint32_*/ parallel();

=== modified file 'storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/issues.txt'
--- a/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/issues.txt	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/ndbjtie/com/mysql/ndbjtie/ndbapi/issues.txt	revid:mikael.ronstrom@stripped
@@ -14,6 +14,7 @@ NdbDictionary.java:        // MMM! suppo
 
 Ndb.java:        // MMM! support <out:BB> or check if needed: ByteBuffer/*_const void *_*/ ptr();
 Ndb.java:        // MMM! support <out:BB> or check if needed: public final native ByteBuffer/*_const void *_*/ ptr();
+// MMM! support mapping <union> or check if needed
 
 NdbDictionary.java:    // MMM! support <out:BB> or check if needed: static public final native char * getValuePtr(NdbRecordConst/*_const NdbRecord *_*/ record, char * row, int/*_Uint32_*/ attrId);
 

=== modified file 'storage/ndb/src/ndbjtie/ndbapi_jtie.hpp'
--- a/storage/ndb/src/ndbjtie/ndbapi_jtie.hpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/src/ndbjtie/ndbapi_jtie.hpp	revid:mikael.ronstrom@stripped
@@ -1,5 +1,5 @@
 /*
- Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010, 2012, 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
@@ -121,6 +121,8 @@ JTIE_DEFINE_PEER_CLASS_MAPPING(Ndb::Key_
                                c_m_n_n_Ndb_Key_part_ptr)
 JTIE_DEFINE_PEER_CLASS_MAPPING(Ndb::Key_part_ptr,
                                c_m_n_n_Ndb_Key_part_ptrArray)
+JTIE_DEFINE_PEER_CLASS_MAPPING(Ndb::PartitionSpec,
+                               c_m_n_n_Ndb_PartitionSpec)
 JTIE_DEFINE_PEER_CLASS_MAPPING(Ndb_cluster_connection,
                                c_m_n_n_Ndb_cluster_connection)
 
@@ -4053,6 +4055,22 @@ Java_com_mysql_ndbjtie_ndbapi_NdbDiction
 
 /*
  * Class:     com_mysql_ndbjtie_ndbapi_NdbDictionary_RecordSpecification
+ * Method:    size
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_com_mysql_ndbjtie_ndbapi_NdbDictionary_00024RecordSpecification_size(JNIEnv * env, jclass cls)
+{
+    TRACE("jint Java_com_mysql_ndbjtie_ndbapi_NdbDictionary_00024RecordSpecification_size(JNIEnv *, jclass)");
+#ifndef NDBJTIE_USE_WRAPPED_VARIANT_FOR_FUNCTION
+    return gcall_fr< ttrait_Uint32, &NdbDictionary::RecordSpecification::size >(env, cls);
+#else
+    return gcall_fr< ttrait_Uint32, &NdbApiWrapper::NdbDictionary__RecordSpecification__size >(env, cls);
+#endif // NDBJTIE_USE_WRAPPED_VARIANT_FOR_FUNCTION
+}
+
+/*
+ * Class:     com_mysql_ndbjtie_ndbapi_NdbDictionary_RecordSpecification
  * Method:    column
  * Signature: ()Lcom/mysql/ndbjtie/ndbapi/NdbDictionary/ColumnConst;
  */
@@ -7984,6 +8002,22 @@ Java_com_mysql_ndbjtie_ndbapi_NdbOperati
 
 /*
  * Class:     com_mysql_ndbjtie_ndbapi_NdbOperation_OperationOptions
+ * Method:    size
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_com_mysql_ndbjtie_ndbapi_NdbOperation_00024OperationOptions_size(JNIEnv * env, jclass cls)
+{
+    TRACE("jint Java_com_mysql_ndbjtie_ndbapi_NdbOperation_00024OperationOptions_size(JNIEnv *, jclass)");
+#ifndef NDBJTIE_USE_WRAPPED_VARIANT_FOR_FUNCTION
+    return gcall_fr< ttrait_Uint32, &NdbOperation::OperationOptions::size >(env, cls);
+#else
+    return gcall_fr< ttrait_Uint32, &NdbApiWrapper::NdbOperation__OperationOptions__size >(env, cls);
+#endif // NDBJTIE_USE_WRAPPED_VARIANT_FOR_FUNCTION
+}
+
+/*
+ * Class:     com_mysql_ndbjtie_ndbapi_NdbOperation_OperationOptions
  * Method:    optionsPresent
  * Signature: ()J
  */
@@ -9244,6 +9278,22 @@ Java_com_mysql_ndbjtie_ndbapi_NdbScanOpe
 
 /*
  * Class:     com_mysql_ndbjtie_ndbapi_NdbScanOperation_ScanOptions
+ * Method:    size
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_com_mysql_ndbjtie_ndbapi_NdbScanOperation_00024ScanOptions_size(JNIEnv * env, jclass cls)
+{
+    TRACE("jint Java_com_mysql_ndbjtie_ndbapi_NdbScanOperation_00024ScanOptions_size(JNIEnv *, jclass)");
+#ifndef NDBJTIE_USE_WRAPPED_VARIANT_FOR_FUNCTION
+    return gcall_fr< ttrait_Uint32, &NdbScanOperation::ScanOptions::size >(env, cls);
+#else
+    return gcall_fr< ttrait_Uint32, &NdbApiWrapper::NdbScanOperation__ScanOptions__size >(env, cls);
+#endif // NDBJTIE_USE_WRAPPED_VARIANT_FOR_FUNCTION
+}
+
+/*
+ * Class:     com_mysql_ndbjtie_ndbapi_NdbScanOperation_ScanOptions
  * Method:    optionsPresent
  * Signature: ()J
  */
@@ -9952,6 +10002,38 @@ Java_com_mysql_ndbjtie_ndbapi_Ndb_00024K
 
 // ---------------------------------------------------------------------------
 
+//#include "com_mysql_ndbjtie_ndbapi_Ndb_PartitionSpec.h"
+
+/*
+ * Class:     com_mysql_ndbjtie_ndbapi_Ndb_PartitionSpec
+ * Method:    size
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_com_mysql_ndbjtie_ndbapi_Ndb_00024PartitionSpec_size(JNIEnv * env, jclass cls)
+{
+    TRACE("jint Java_com_mysql_ndbjtie_ndbapi_Ndb_00024PartitionSpec_size(JNIEnv *, jclass)");
+#ifndef NDBJTIE_USE_WRAPPED_VARIANT_FOR_FUNCTION
+    return gcall_fr< ttrait_Uint32, &Ndb::PartitionSpec::size >(env, cls);
+#else
+    return gcall_fr< ttrait_Uint32, &NdbApiWrapper::Ndb__PartitionSpec__size >(env, cls);
+#endif // NDBJTIE_USE_WRAPPED_VARIANT_FOR_FUNCTION
+}
+
+/*
+ * Class:     com_mysql_ndbjtie_ndbapi_Ndb_PartitionSpec
+ * Method:    type
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL
+Java_com_mysql_ndbjtie_ndbapi_Ndb_00024PartitionSpec_type(JNIEnv * env, jobject obj)
+{
+    TRACE("jint Java_com_mysql_ndbjtie_ndbapi_Ndb_00024PartitionSpec_type(JNIEnv *, jobject)");
+    return gget< ttrait_c_m_n_n_Ndb_PartitionSpec_t, ttrait_Uint32, &Ndb::PartitionSpec::type >(env, obj);
+}
+
+// ---------------------------------------------------------------------------
+
 //#include "com_mysql_ndbjtie_ndbapi_Ndb_cluster_connection.h"
 
 /*
@@ -10002,8 +10084,8 @@ Java_com_mysql_ndbjtie_ndbapi_Ndb_1clust
  * Class:     com_mysql_ndbjtie_ndbapi_Ndb_cluster_connection
  * Method:    create
  * Signature: (Ljava/lang/String;I)Lcom/mysql/ndbjtie/ndbapi/Ndb_cluster_connection;
- */ 
-JNIEXPORT jobject JNICALL 
+ */
+JNIEXPORT jobject JNICALL
 Java_com_mysql_ndbjtie_ndbapi_Ndb_1cluster_1connection_create__Ljava_lang_String_2I
   (JNIEnv * env, jclass cls, jstring p0, jint p1)
 {

=== modified file 'storage/ndb/test/ndbapi/flexAsynch.cpp'
--- a/storage/ndb/test/ndbapi/flexAsynch.cpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/test/ndbapi/flexAsynch.cpp	revid:mikael.ronstrom@stripped
@@ -36,7 +36,7 @@
 #define MAX_PARTS 4 
 #define MAX_SEEK 16 
 #define MAXSTRLEN 16 
-#define MAXATTR 127 
+#define MAXATTR 511 
 #define MAXTABLES 1
 #define NDB_MAXTHREADS 128
 #define NDB_MAX_NODES 48

=== modified file 'storage/ndb/test/ndbapi/testSystemRestart.cpp'
--- a/storage/ndb/test/ndbapi/testSystemRestart.cpp	revid:mikael.ronstrom@stripped
+++ b/storage/ndb/test/ndbapi/testSystemRestart.cpp	revid:mikael.ronstrom@stripped
@@ -2440,7 +2440,6 @@ TESTCASE("SR1", 
 	 "12. Restart cluster with error insert 5020 and verify records\n"){ 
   INITIALIZER(runWaitStarted);
   STEP(runSystemRestart1);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR2", 
 	 "Basic system restart test. Focus on testing restart from LCP\n"
@@ -2458,7 +2457,6 @@ TESTCASE("SR2", 
 	 "10. Restart cluster and verify records\n"){
   INITIALIZER(runWaitStarted);
   STEP(runSystemRestart2);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_UNDO", 
 	 "System restart test. Focus on testing of undologging\n"
@@ -2470,13 +2468,11 @@ TESTCASE("SR_UNDO", 
 	 "Restart the system\n"){
   INITIALIZER(runWaitStarted);
   STEP(runSystemRestartTestUndoLog);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_FULLDB", 
 	 "System restart test. Test to restart when DB is full.\n"){
   INITIALIZER(runWaitStarted);
   STEP(runSystemRestartTestFullDb);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR3", 
 	 "System restart test. Focus on testing restart from with\n"
@@ -2493,7 +2489,6 @@ TESTCASE("SR3", 
 	 "* 10. Restart cluster and verify records\n"){
   INITIALIZER(runWaitStarted);
   STEP(runSystemRestart3);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR4", 
 	 "System restart test. Focus on testing restart from with\n"
@@ -2511,7 +2506,6 @@ TESTCASE("SR4", 
 	 "* 10. Restart cluster and verify records\n"){
   INITIALIZER(runWaitStarted);
   STEP(runSystemRestart4);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR5", 
 	 "As SR4 but making restart aborts\n"
@@ -2527,7 +2521,6 @@ TESTCASE("SR5", 
 	 "* 10. Restart cluster and verify records\n"){
   INITIALIZER(runWaitStarted);
   STEP(runSystemRestart5);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR6", 
 	 "Perform system restart with some nodes having FS others wo/\n"
@@ -2538,7 +2531,6 @@ TESTCASE("SR6", 
   INITIALIZER(runWaitStarted);
   INITIALIZER(runClearTable);
   STEP(runSystemRestart6);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR7", 
 	 "Perform partition win system restart\n"
@@ -2551,7 +2543,6 @@ TESTCASE("SR7", 
   INITIALIZER(runWaitStarted);
   INITIALIZER(runClearTable);
   STEP(runSystemRestart7);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR8", 
 	 "Perform partition win system restart with other nodes delayed\n"
@@ -2564,7 +2555,6 @@ TESTCASE("SR8", 
   INITIALIZER(runWaitStarted);
   INITIALIZER(runClearTable);
   STEP(runSystemRestart8);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR9", 
 	 "Perform partition win system restart with other nodes delayed\n"
@@ -2577,21 +2567,18 @@ TESTCASE("SR9", 
   INITIALIZER(runWaitStarted);
   INITIALIZER(runClearTable);
   STEP(runSystemRestart9);
-  FINALIZER(runClearTable);
 }
 TESTCASE("Bug18385", 
 	 "Perform partition system restart with other nodes with higher GCI"){
   INITIALIZER(runWaitStarted);
   INITIALIZER(runClearTable);
   STEP(runBug18385);
-  FINALIZER(runClearTable);
 }
 TESTCASE("Bug21536", 
 	 "Perform partition system restart with other nodes with higher GCI"){
   INITIALIZER(runWaitStarted);
   INITIALIZER(runClearTable);
   STEP(runBug21536);
-  FINALIZER(runClearTable);
 }
 TESTCASE("Bug24664",
 	 "Check handling of LCP skip/keep")
@@ -2599,7 +2586,6 @@ TESTCASE("Bug24664",
   INITIALIZER(runWaitStarted);
   INITIALIZER(runClearTable);
   STEP(runBug24664);
-  FINALIZER(runClearTable);
 }
 TESTCASE("Bug27434",
 	 "")
@@ -2614,14 +2600,12 @@ TESTCASE("SR_DD_1", "")
   INITIALIZER(clearOldBackups);
   STEP(runStopper);
   STEP(runSR_DD_1);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_1b", "")
 {
   INITIALIZER(runWaitStarted);
   INITIALIZER(clearOldBackups);
   STEP(runSR_DD_1);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_1_LCP", "")
 {
@@ -2631,7 +2615,6 @@ TESTCASE("SR_DD_1_LCP", "")
   INITIALIZER(clearOldBackups);
   STEP(runStopper);
   STEP(runSR_DD_1);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_1b_LCP", "")
 {
@@ -2639,7 +2622,6 @@ TESTCASE("SR_DD_1b_LCP", "")
   INITIALIZER(runWaitStarted);
   INITIALIZER(clearOldBackups);
   STEP(runSR_DD_1);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_2", "")
 {
@@ -2648,14 +2630,12 @@ TESTCASE("SR_DD_2", "")
   INITIALIZER(clearOldBackups);
   STEP(runStopper);
   STEP(runSR_DD_2);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_2b", "")
 {
   INITIALIZER(runWaitStarted);
   INITIALIZER(clearOldBackups);
   STEP(runSR_DD_2);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_2_LCP", "")
 {
@@ -2665,7 +2645,6 @@ TESTCASE("SR_DD_2_LCP", "")
   INITIALIZER(clearOldBackups);
   STEP(runStopper);
   STEP(runSR_DD_2);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_2b_LCP", "")
 {
@@ -2673,7 +2652,6 @@ TESTCASE("SR_DD_2b_LCP", "")
   INITIALIZER(runWaitStarted);
   INITIALIZER(clearOldBackups);
   STEP(runSR_DD_2);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_3", "")
 {
@@ -2682,14 +2660,12 @@ TESTCASE("SR_DD_3", "")
   INITIALIZER(clearOldBackups);
   STEP(runStopper);
   STEP(runSR_DD_3);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_3b", "")
 {
   INITIALIZER(runWaitStarted);
   INITIALIZER(clearOldBackups);
   STEP(runSR_DD_3);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_3_LCP", "")
 {
@@ -2699,7 +2675,6 @@ TESTCASE("SR_DD_3_LCP", "")
   INITIALIZER(clearOldBackups);
   STEP(runStopper);
   STEP(runSR_DD_3);
-  FINALIZER(runClearTable);
 }
 TESTCASE("SR_DD_3b_LCP", "")
 {
@@ -2707,7 +2682,6 @@ TESTCASE("SR_DD_3b_LCP", "")
   INITIALIZER(runWaitStarted);
   INITIALIZER(clearOldBackups);
   STEP(runSR_DD_3);
-  FINALIZER(runClearTable);
 }
 TESTCASE("Bug29167", "")
 {
@@ -2725,21 +2699,18 @@ TESTCASE("Bug28770",
   INITIALIZER(runWaitStarted);
   INITIALIZER(runClearTable);
   STEP(runBug28770);
-  FINALIZER(runClearTable);
 }
 TESTCASE("Bug22696", "")
 {
   INITIALIZER(runWaitStarted);
   INITIALIZER(runLoadTable);
   INITIALIZER(runBug22696);
-  FINALIZER(runClearTable);
 }
 TESTCASE("to", "Take-over during SR")
 {
   INITIALIZER(runWaitStarted);
   INITIALIZER(runLoadTable);
   INITIALIZER(runTO);
-  FINALIZER(runClearTable);
 }
 TESTCASE("basic", "")
 {
@@ -2756,7 +2727,6 @@ TESTCASE("Bug41915", "")
   INITIALIZER(runWaitStarted);
   STEP(runStopper);
   STEP(runSR_DD_2);
-  FINALIZER(runClearTable);
 }
 TESTCASE("Bug45154", "")
 {

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.5-cluster-7.2 branch (mikael.ronstrom:3720 to 3722) Mikael Ronstrom23 Jan