List:Commits« Previous MessageNext Message »
From:Maitrayi Sabaratnam Date:November 26 2009 4:40pm
Subject:bzr commit into mysql-5.1-telco-7.0-mai branch (msabaratnam:3207)
View as plain text  
#At file:///export/home/tmp/maitrayi/mysql-src/mysql-5.1-telco-7.0-mai/ based on revid:msabaratnam@stripped

 3207 Maitrayi Sabaratnam	2009-11-26 [merge]
      Catching up 7-0 branch.

    added:
      mysql-test/suite/ndb/r/ndb_short_sigs.result
      mysql-test/suite/ndb/t/ndb_short_sigs.cnf
      mysql-test/suite/ndb/t/ndb_short_sigs.test
    modified:
      scripts/make_win_bin_dist
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster_connection.cc
      storage/ndb/include/kernel/signaldata/ConfigChange.hpp
      storage/ndb/include/kernel/signaldata/GetTabInfo.hpp
      storage/ndb/include/ndb_version.h.in
      storage/ndb/include/ndbapi/NdbOperation.hpp
      storage/ndb/src/common/util/BaseString.cpp
      storage/ndb/src/mgmsrv/CMakeLists.txt
      storage/ndb/src/mgmsrv/Config.cpp
      storage/ndb/src/mgmsrv/Config.hpp
      storage/ndb/src/mgmsrv/ConfigManager.cpp
      storage/ndb/src/mgmsrv/MgmtSrvr.hpp
      storage/ndb/src/mgmsrv/main.cpp
      storage/ndb/src/mgmsrv/testConfig.cpp
      storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
      storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
      storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
      storage/ndb/src/ndbapi/NdbImpl.hpp
      storage/ndb/src/ndbapi/NdbOperationExec.cpp
      storage/ndb/src/ndbapi/NdbScanOperation.cpp
      storage/ndb/src/ndbapi/Ndbinit.cpp
      storage/ndb/src/ndbapi/TransporterFacade.hpp
      storage/ndb/src/ndbapi/ndb_cluster_connection.cpp
      storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
      storage/ndb/src/ndbapi/ndberror.c
      storage/ndb/test/include/NDBT_Test.hpp
      storage/ndb/test/ndbapi/testMgmd.cpp
      storage/ndb/test/ndbapi/testNdbinfo.cpp
      storage/ndb/test/ndbapi/testPartitioning.cpp
      storage/ndb/test/run-test/daily-basic-tests.txt
      storage/ndb/test/src/CMakeLists.txt
      storage/ndb/test/src/Makefile.am
      storage/ndb/test/src/NDBT_Test.cpp
      storage/ndb/tools/ndbinfo_sql.cpp
=== added file 'mysql-test/suite/ndb/r/ndb_short_sigs.result'
--- a/mysql-test/suite/ndb/r/ndb_short_sigs.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_short_sigs.result	2009-11-18 11:05:02 +0000
@@ -0,0 +1,105 @@
+create table t1 (
+th int primary key, 
+un int, 
+de int, 
+rb varchar(1000), 
+al longtext, 
+key(de),
+unique(rb)) 
+engine=ndb;
+insert into t1 values (1, 1, 1, repeat('O', 1000), repeat('L', 60000));
+insert into t1 values (2, 2, 2, repeat('W',  999), repeat('B', 60001));
+insert into t1 values (3, 3, 3, repeat('P',  998), repeat('P', 60002));
+insert into t1 values (4, 4, 4, repeat('Q',  997), repeat('E', 60003));
+insert into t1 values (5, 5, 5, repeat('E',  996), repeat('A', 60004));
+select th, un, de, length(rb), length(al) 
+from t1 
+where th in (2,4) 
+order by th;
+th	un	de	length(rb)	length(al)
+2	2	2	999	60001
+4	4	4	997	60003
+select th, un, de, length(rb), length(al) 
+from t1 
+where rb 
+in (repeat('O', 1000), repeat('Q', 997))
+order by th;
+th	un	de	length(rb)	length(al)
+1	1	1	1000	60000
+4	4	4	997	60003
+select th, un, de, length(rb), length(al)
+from t1
+where de between 3 and 5
+order by th;
+th	un	de	length(rb)	length(al)
+3	3	3	998	60002
+4	4	4	997	60003
+5	5	5	996	60004
+select th, un, de, length(rb), length(al) 
+from t1 
+order by th;
+th	un	de	length(rb)	length(al)
+1	1	1	1000	60000
+2	2	2	999	60001
+3	3	3	998	60002
+4	4	4	997	60003
+5	5	5	996	60004
+update t1 
+set un=6, de=6, rb= repeat('S', 995), al = repeat('O', 60005)
+where th = 1;
+update t1
+set un=7, de=7, al = repeat('F', 60006)
+where rb = repeat('W', 999);
+update t1
+set un= un + 5, rb = repeat('U', 1000 - un), al = repeat('U', 60000 + un)
+where de >= 3 and de <= 5;
+select th, un, de, length(rb), length(al) 
+from t1 
+order by th;
+th	un	de	length(rb)	length(al)
+1	6	6	995	60005
+2	7	7	999	60006
+3	8	3	992	60008
+4	9	4	991	60009
+5	10	5	990	60010
+alter table t1 add column extra varchar(2000);
+Warnings:
+Warning	1478	Converted FIXED field to DYNAMIC to enable on-line ADD COLUMN
+update t1 set extra = repeat(rb, 2);
+select th, un, de, length(rb), length(al), length(extra)
+from t1 
+order by th;
+th	un	de	length(rb)	length(al)	length(extra)
+1	6	6	995	60005	1990
+2	7	7	999	60006	1998
+3	8	3	992	60008	1984
+4	9	4	991	60009	1982
+5	10	5	990	60010	1980
+select th, un, de, length(rb), length(al), length(extra)
+from t1
+where extra in (
+repeat('U', 2000),
+repeat('U', 1998),
+repeat('U', 1996),
+repeat('U', 1994),
+repeat('U', 1992),
+repeat('U', 1990),
+repeat('U', 1988),
+repeat('U', 1986),
+repeat('U', 1984),
+repeat('U', 1982),
+repeat('U', 1980),
+repeat('U', 1978),
+repeat('U', 1976),
+repeat('U', 1974),
+repeat('U', 1972),
+repeat('U', 1970),
+repeat('U', 1968),
+repeat('U', 1966),
+repeat('U', 1964))
+order by th;
+th	un	de	length(rb)	length(al)	length(extra)
+3	8	3	992	60008	1984
+4	9	4	991	60009	1982
+5	10	5	990	60010	1980
+drop table t1;

=== added file 'mysql-test/suite/ndb/t/ndb_short_sigs.cnf'
--- a/mysql-test/suite/ndb/t/ndb_short_sigs.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_short_sigs.cnf	2009-11-18 11:05:02 +0000
@@ -0,0 +1,9 @@
+#
+# Config used when testing short NdbApi request handling
+# functionality
+#
+!include suite/ndb/my.cnf
+
+[ENV]
+# Activate short signal requests
+NDB_FORCE_SHORT_REQUESTS=Y

=== added file 'mysql-test/suite/ndb/t/ndb_short_sigs.test'
--- a/mysql-test/suite/ndb/t/ndb_short_sigs.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_short_sigs.test	2009-11-18 11:05:02 +0000
@@ -0,0 +1,102 @@
+-- source include/have_ndb.inc
+
+
+# Create table with unique key, ordered index + blob
+
+create table t1 (
+        th int primary key, 
+        un int, 
+        de int, 
+        rb varchar(1000), 
+        al longtext, 
+        key(de),
+        unique(rb)) 
+        engine=ndb;
+
+insert into t1 values (1, 1, 1, repeat('O', 1000), repeat('L', 60000));
+insert into t1 values (2, 2, 2, repeat('W',  999), repeat('B', 60001));
+insert into t1 values (3, 3, 3, repeat('P',  998), repeat('P', 60002));
+insert into t1 values (4, 4, 4, repeat('Q',  997), repeat('E', 60003));
+insert into t1 values (5, 5, 5, repeat('E',  996), repeat('A', 60004));
+
+# Pk lookup
+select th, un, de, length(rb), length(al) 
+        from t1 
+        where th in (2,4) 
+        order by th;
+
+# Uk lookup
+select th, un, de, length(rb), length(al) 
+        from t1 
+        where rb 
+        in (repeat('O', 1000), repeat('Q', 997))
+        order by th;
+
+# Secondary Index scan
+select th, un, de, length(rb), length(al)
+        from t1
+        where de between 3 and 5
+        order by th;
+
+# Table scan
+select th, un, de, length(rb), length(al) 
+        from t1 
+        order by th;
+
+# Update via Pk
+update t1 
+        set un=6, de=6, rb= repeat('S', 995), al = repeat('O', 60005)
+        where th = 1;
+
+# Update via Uk
+update t1
+        set un=7, de=7, al = repeat('F', 60006)
+        where rb = repeat('W', 999);
+
+# Update via Index Scan
+update t1
+        set un= un + 5, rb = repeat('U', 1000 - un), al = repeat('U', 60000 + un)
+        where de >= 3 and de <= 5;
+
+# Table scan
+select th, un, de, length(rb), length(al) 
+        from t1 
+        order by th;
+
+# Online alter table
+alter table t1 add column extra varchar(2000);
+
+# Table scanning update
+update t1 set extra = repeat(rb, 2);
+
+# Table scan
+select th, un, de, length(rb), length(al), length(extra)
+        from t1 
+        order by th;
+
+# Table scan with large pushed filter
+select th, un, de, length(rb), length(al), length(extra)
+        from t1
+        where extra in (
+        repeat('U', 2000),
+        repeat('U', 1998),
+        repeat('U', 1996),
+        repeat('U', 1994),
+        repeat('U', 1992),
+        repeat('U', 1990),
+        repeat('U', 1988),
+        repeat('U', 1986),
+        repeat('U', 1984),
+        repeat('U', 1982),
+        repeat('U', 1980),
+        repeat('U', 1978),
+        repeat('U', 1976),
+        repeat('U', 1974),
+        repeat('U', 1972),
+        repeat('U', 1970),
+        repeat('U', 1968),
+        repeat('U', 1966),
+        repeat('U', 1964))
+        order by th;
+
+drop table t1;

=== modified file 'scripts/make_win_bin_dist'
--- a/scripts/make_win_bin_dist	2009-10-01 07:16:52 +0000
+++ b/scripts/make_win_bin_dist	2009-11-17 16:30:37 +0000
@@ -340,7 +340,7 @@ fi
 mkdir $DESTDIR/mysql-test
 cp mysql-test/mysql-test-run.pl $DESTDIR/mysql-test/
 cp mysql-test/README $DESTDIR/mysql-test/
-cp -R mysql-test/{t,r,include,suite,std_data,lib} $DESTDIR/mysql-test/
+cp -R mysql-test/{t,r,include,suite,std_data,lib,collections} $DESTDIR/mysql-test/
 
 # Note that this will not copy "extra" if a soft link
 if [ -d mysql-test/extra ] ; then

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2009-11-08 12:52:27 +0000
+++ b/sql/ha_ndbcluster.cc	2009-11-18 13:06:20 +0000
@@ -1379,7 +1379,7 @@ void ha_ndbcluster::release_blobs_buffer
   DBUG_ENTER("releaseBlobsBuffer");
   if (m_blobs_buffer_size > 0)
   {
-    DBUG_PRINT("info", ("Deleting blobs buffer, size %u", m_blobs_buffer_size));
+    DBUG_PRINT("info", ("Deleting blobs buffer, size %llu", m_blobs_buffer_size));
     my_free(m_blobs_buffer, MYF(MY_ALLOW_ZERO_PTR));
     m_blobs_buffer= 0;
     m_blobs_row_total_size= 0;
@@ -12597,6 +12597,7 @@ int ha_ndbcluster::alter_table_phase1(TH
     DBUG_PRINT("info", ("Failed to start schema transaction"));
     ERR_PRINT(dict->getNdbError());
     error= ndb_to_mysql_error(&dict->getNdbError());
+    table->file->print_error(error, MYF(0));
     goto err;
   }
 

=== modified file 'sql/ha_ndbcluster_connection.cc'
--- a/sql/ha_ndbcluster_connection.cc	2009-11-08 18:23:30 +0000
+++ b/sql/ha_ndbcluster_connection.cc	2009-11-17 15:57:14 +0000
@@ -72,7 +72,7 @@ int ndbcluster_connect(int (*connect_cal
     DBUG_PRINT("error",("Ndb_cluster_connection(%s)",
                         opt_ndb_connectstring));
     my_errno= HA_ERR_OUT_OF_MEM;
-    goto ndbcluster_connect_error;
+    DBUG_RETURN(-1);
   }
   {
     char buf[128];
@@ -89,14 +89,14 @@ int ndbcluster_connect(int (*connect_cal
     sql_print_error("NDB: failed to allocate global ndb object");
     DBUG_PRINT("error", ("failed to create global ndb object"));
     my_errno= HA_ERR_OUT_OF_MEM;
-    goto ndbcluster_connect_error;
+    DBUG_RETURN(-1);
   }
   if (g_ndb->init() != 0)
   {
     DBUG_PRINT("error", ("%d  message: %s",
                          g_ndb->getNdbError().code,
                          g_ndb->getNdbError().message));
-    goto ndbcluster_connect_error;
+    DBUG_RETURN(-1);
   }
 
   /* Connect to management server */
@@ -110,7 +110,7 @@ int ndbcluster_connect(int (*connect_cal
       break;
     do_retry_sleep(100);
     if (abort_loop)
-      goto ndbcluster_connect_error;
+      DBUG_RETURN(-1);
   }
 
   {
@@ -131,7 +131,7 @@ int ndbcluster_connect(int (*connect_cal
                         i);
         DBUG_PRINT("error",("Ndb_cluster_connection[%u](%s)",
                             i, opt_ndb_connectstring));
-        goto ndbcluster_connect_error;
+        DBUG_RETURN(-1);
       }
       {
         char buf[128];
@@ -200,7 +200,7 @@ int ndbcluster_connect(int (*connect_cal
       {
         sql_print_error("NDB[%u]: failed to start connect thread", i);
         DBUG_PRINT("error", ("g_ndb_cluster_connection->start_connect_thread()"));
-        goto ndbcluster_connect_error;
+        DBUG_RETURN(-1);
       }
     }
 #ifndef DBUG_OFF
@@ -221,11 +221,9 @@ int ndbcluster_connect(int (*connect_cal
     sql_print_error("NDB: error (%u) %s",
                     g_ndb_cluster_connection->get_latest_error(),
                     g_ndb_cluster_connection->get_latest_error_msg());
-    goto ndbcluster_connect_error;
+    DBUG_RETURN(-1);
   }
   DBUG_RETURN(0);
-ndbcluster_connect_error:
-  DBUG_RETURN(-1);
 }
 
 void ndbcluster_disconnect(void)

=== modified file 'storage/ndb/include/kernel/signaldata/ConfigChange.hpp'
--- a/storage/ndb/include/kernel/signaldata/ConfigChange.hpp	2009-09-25 07:57:29 +0000
+++ b/storage/ndb/include/kernel/signaldata/ConfigChange.hpp	2009-11-17 18:13:29 +0000
@@ -204,11 +204,13 @@ class ConfigCheckReq  {
   friend class ConfigManager;
 
 public:
-  STATIC_CONST( SignalLength = 2 );
+  STATIC_CONST( SignalLengthBeforeChecksum = 2 );
+  STATIC_CONST( SignalLength = 3 );
 
 private:
   Uint32 state;
   Uint32 generation;
+  Uint32 checksum;
 };
 
 
@@ -246,7 +248,8 @@ class ConfigCheckRef  {
 
   enum ErrorCode {
     WrongState                 = 1,
-    WrongGeneration            = 2
+    WrongGeneration            = 2,
+    WrongChecksum              = 3
   };
 
   static const char* errorMessage(Uint32 error) {
@@ -255,6 +258,8 @@ class ConfigCheckRef  {
       return "Wrong state";
     case WrongGeneration:
       return "Wrong generation";
+    case WrongChecksum:
+      return "Wrong checksum";
 
     default:
       return "ConfigCheckRef, unknown error";

=== modified file 'storage/ndb/include/kernel/signaldata/GetTabInfo.hpp'
--- a/storage/ndb/include/kernel/signaldata/GetTabInfo.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/include/kernel/signaldata/GetTabInfo.hpp	2009-11-18 11:05:02 +0000
@@ -74,6 +74,9 @@ class GetTabInfoRef {
   friend bool printGET_TABINFO_REF(FILE *, const Uint32 *, Uint32, Uint16);    
 public:
   STATIC_CONST( SignalLength = 7 );
+  /* 6.3 <-> 7.0 upgrade code */
+  STATIC_CONST( OriginalSignalLength = 5 );
+  STATIC_CONST( OriginalErrorOffset = 4 );
 public:
   Uint32 senderData;
   Uint32 senderRef;

=== modified file 'storage/ndb/include/ndb_version.h.in'
--- a/storage/ndb/include/ndb_version.h.in	2009-11-02 17:15:29 +0000
+++ b/storage/ndb/include/ndb_version.h.in	2009-11-18 11:05:02 +0000
@@ -102,11 +102,15 @@ Uint32 ndbGetOwnVersion();
 #define NDBD_MICRO_GCP_62 NDB_MAKE_VERSION(6,2,5)
 #define NDBD_MICRO_GCP_63 NDB_MAKE_VERSION(6,3,2)
 #define NDBD_RAW_LCP MAKE_VERSION(6,3,11)
+#define NDBD_LONG_TCKEYREQ NDB_MAKE_VERSION(6,4,0)
 #define NDBD_LONG_LQHKEYREQ MAKE_VERSION(6,4,0)
 #define NDBD_MAX_RECVBYTESIZE_32K MAKE_VERSION(6,3,18)
+#define NDBD_LONG_SCANTABREQ NDB_MAKE_VERSION(6,4,0)
 #define NDBD_LONG_SCANFRAGREQ MAKE_VERSION(6,4,0)
 #define NDBD_MT_LQH_VERSION MAKE_VERSION(6,4,0)
 
+#define NDBD_SCHEMA_TRANS_VERSION NDB_MAKE_VERSION(6,4,0)
+
 
 static
 inline

=== modified file 'storage/ndb/include/ndbapi/NdbOperation.hpp'
--- a/storage/ndb/include/ndbapi/NdbOperation.hpp	2009-10-07 02:56:19 +0000
+++ b/storage/ndb/include/ndbapi/NdbOperation.hpp	2009-11-18 18:43:58 +0000
@@ -36,6 +36,7 @@ class NdbBlob;
 class TcKeyReq;
 class NdbRecord;
 class NdbInterpretedCode;
+struct GenericSectionPtr;
 
 /**
  * @class NdbOperation
@@ -1208,8 +1209,8 @@ protected:
  * was sent, then the connection object is told about this situation.
  *****************************************************************************/
 
+  int    doSendKeyReq(int processorId, GenericSectionPtr* secs, Uint32 numSecs);
   int    doSend(int ProcessorId, Uint32 lastFlag);
-  int    doSendNdbRecord(int aNodeId);
   virtual int	 prepareSend(Uint32  TC_ConnectPtr,
                              Uint64  TransactionId,
 			     AbortOption);

=== modified file 'storage/ndb/src/common/util/BaseString.cpp'
--- a/storage/ndb/src/common/util/BaseString.cpp	2009-07-16 16:36:20 +0000
+++ b/storage/ndb/src/common/util/BaseString.cpp	2009-11-13 11:11:12 +0000
@@ -500,9 +500,10 @@ BaseString
 BaseString::getPrettyText(unsigned size, const Uint32 data[])
 {
   const char* delimiter = "";
-  unsigned i, found = 0, MAX_BITS = 8 * size;
+  unsigned found = 0;
+  const unsigned MAX_BITS = sizeof(Uint32) * 8 * size;
   BaseString to;
-  for (i = 0; i < MAX_BITS; i++)
+  for (unsigned i = 0; i < MAX_BITS; i++)
   {
     if (BitmaskImpl::get(size, data, i))
     {
@@ -521,9 +522,9 @@ BaseString
 BaseString::getPrettyTextShort(unsigned size, const Uint32 data[])
 {
   const char* delimiter = "";
-  unsigned i, MAX_BITS = 8 * size;
+  const unsigned MAX_BITS = sizeof(Uint32) * 8 * size;
   BaseString to;
-  for (i = 0; i < MAX_BITS; i++)
+  for (unsigned i = 0; i < MAX_BITS; i++)
   {
     if (BitmaskImpl::get(size, data, i))
     {

=== modified file 'storage/ndb/src/mgmsrv/CMakeLists.txt'
--- a/storage/ndb/src/mgmsrv/CMakeLists.txt	2009-11-13 04:50:47 +0000
+++ b/storage/ndb/src/mgmsrv/CMakeLists.txt	2009-11-17 18:13:57 +0000
@@ -45,3 +45,7 @@ ADD_EXECUTABLE(ndb_mgmd
 TARGET_LINK_LIBRARIES(ndb_mgmd ndbconf)
 
 INSTALL(TARGETS ndb_mgmd DESTINATION libexec)
+
+ADD_EXECUTABLE(MgmConfig-t
+               testConfig.cpp)
+TARGET_LINK_LIBRARIES(ndb_mgmd ndbconf)

=== modified file 'storage/ndb/src/mgmsrv/Config.cpp'
--- a/storage/ndb/src/mgmsrv/Config.cpp	2009-10-09 12:47:49 +0000
+++ b/storage/ndb/src/mgmsrv/Config.cpp	2009-11-17 18:13:29 +0000
@@ -824,3 +824,19 @@ Config::get_nodemask(NodeBitmask& mask,
   }
 }
 
+
+Uint32
+Config::checksum(void) const {
+  Uint32 chk;
+
+  UtilBuffer buf;
+  pack(buf);
+
+  // Checksum is the last 4 bytes in buffer
+  const char* chk_ptr = (const char*)buf.get_data();
+  chk_ptr += buf.length() - sizeof(Uint32);
+  chk = *(Uint32*) chk_ptr;
+
+  return chk;
+}
+

=== modified file 'storage/ndb/src/mgmsrv/Config.hpp'
--- a/storage/ndb/src/mgmsrv/Config.hpp	2009-09-25 07:57:29 +0000
+++ b/storage/ndb/src/mgmsrv/Config.hpp	2009-11-17 18:13:29 +0000
@@ -120,6 +120,14 @@ public:
   bool equal(const Config*, const unsigned* exclude = NULL) const;
 
   /*
+    Return the checksum of the config. The checksum can be used to compare
+    two configs without having the whole config available(for example on
+    a remote host). It can also be printed to log files for manual verification
+    that same config is used
+  */
+  Uint32 checksum(void) const;
+
+  /*
     Return bitmask of all defined nodes of a certain type
     returns all defined nodes by default.
    */

=== modified file 'storage/ndb/src/mgmsrv/ConfigManager.cpp'
--- a/storage/ndb/src/mgmsrv/ConfigManager.cpp	2009-10-27 16:50:41 +0000
+++ b/storage/ndb/src/mgmsrv/ConfigManager.cpp	2009-11-17 18:13:29 +0000
@@ -1323,6 +1323,22 @@ ConfigManager::execCONFIG_CHANGE_REQ(Sig
 }
 
 
+static Uint32
+config_check_checksum(const Config* config)
+{
+  Config copy(config);
+
+  // Make constants of a few values in SYSTEM section that are
+  // not part of the  checksum used for "config check"
+  copy.setName("CHECKSUM");
+  copy.setPrimaryMgmNode(0);
+
+  Uint32 checksum = copy.checksum();
+
+  return checksum;
+}
+
+
 void
 ConfigManager::execCONFIG_CHECK_REQ(SignalSender& ss, SimpleSignal* sig)
 {
@@ -1337,12 +1353,24 @@ ConfigManager::execCONFIG_CHECK_REQ(Sign
 
   Uint32 generation = m_config->getGeneration();
 
-  g_eventLogger->debug("Got CONFIG_CHECK_REQ from node: %d. "   \
-                       "generation: %d, other_generation: %d, " \
-                       "our state: %d, other state: %d",
-                       nodeId, generation, other_generation,
-                       m_config_state, other_state);
+  // checksum
+  Uint32 checksum = config_check_checksum(m_config);
+  Uint32 other_checksum = req->checksum;
+  if (sig->header.theLength == ConfigCheckReq::SignalLengthBeforeChecksum)
+  {
+    // Other side uses old version without checksum, use our checksum to
+    // bypass the checks
+    g_eventLogger->debug("Other mgmd does not have checksum, using own");
+    other_checksum = checksum;
+  }
 
+  g_eventLogger->debug("Got CONFIG_CHECK_REQ from node: %d. "
+                       "Our generation: %d, other generation: %d, "
+                       "our state: %d, other state: %d, "
+                       "our checksum: 0x%.8x, other checksum: 0x%.8x",
+                       nodeId, generation, other_generation,
+                       m_config_state, other_state,
+                       checksum, other_checksum);
 
   switch (m_config_state)
   {
@@ -1376,6 +1404,17 @@ ConfigManager::execCONFIG_CHECK_REQ(Sign
                          m_config_state, other_state);
       return;
     }
+
+    if (other_checksum != checksum)
+    {
+      g_eventLogger->warning("Refusing other node, it has different "
+                             "checksum: 0x%.8x, expected: 0x%.8x",
+                             other_checksum, checksum);
+      sendConfigCheckRef(ss, from, ConfigCheckRef::WrongChecksum,
+                         generation, other_generation,
+                         m_config_state, other_state);
+      return;
+    }
     break;
 
   case CS_CONFIRMED:
@@ -1393,7 +1432,18 @@ ConfigManager::execCONFIG_CHECK_REQ(Sign
 
     if (other_generation == generation)
     {
-      ;// OK
+      // Same generation, make sure it has same checksum
+      if (other_checksum != checksum)
+      {
+        g_eventLogger->warning("Refusing other node, it has different "
+                               "checksum: 0x%.8x, expected: 0x%.8x",
+                               other_checksum, checksum);
+        sendConfigCheckRef(ss, from, ConfigCheckRef::WrongChecksum,
+                           generation, other_generation,
+                           m_config_state, other_state);
+        return;
+      }
+      // OK!
     }
     else if (other_generation < generation)
     {
@@ -1429,17 +1479,15 @@ ConfigManager::sendConfigCheckReq(Signal
     CAST_PTR(ConfigCheckReq, ssig.getDataPtrSend());
   req->state =        m_config_state;
   req->generation =   m_config->getGeneration();
+  req->checksum =     config_check_checksum(m_config);
 
-  BaseString buf("Sending CONFIG_CHECK_REQ to node(s) ");
-  unsigned i = 0;
-  while((i = to.find(i+1)) != NodeBitmask::NotFound)
-    buf.appfmt("%d ", i);
-  g_eventLogger->debug(buf);
+  g_eventLogger->debug("Sending CONFIG_CHECK_REQ to %s",
+                       BaseString::getPrettyText(to).c_str());
 
   require(m_waiting_for.isclear());
   m_waiting_for = ss.broadcastSignal(to, ssig, MGM_CONFIG_MAN,
-                                GSN_CONFIG_CHECK_REQ,
-                                ConfigCheckReq::SignalLength);
+                                     GSN_CONFIG_CHECK_REQ,
+                                     ConfigCheckReq::SignalLength);
 }
 
 static bool
@@ -1559,7 +1607,8 @@ ConfigManager::execCONFIG_CHECK_REF(Sign
                       m_config_state);
 
   assert(ref->generation != ref->expected_generation ||
-         ref->state != ref->expected_state);
+         ref->state != ref->expected_state ||
+         ref->error == ConfigCheckRef::WrongChecksum);
   if((Uint32)m_config_state != ref->state)
   {
     // The config state changed while this check was in the air
@@ -1638,6 +1687,15 @@ ConfigManager::execCONFIG_CHECK_REF(Sign
     break;
   }
 
+  if (ref->error == ConfigCheckRef::WrongChecksum &&
+      m_node_id < nodeId)
+  {
+    g_eventLogger->warning("Ignoring CONFIG_CHECK_REF for wrong checksum "
+                           "other node has higher node id and should "
+                           "shutdown");
+    return;
+  }
+
   g_eventLogger->error("Terminating");
   exit(1);
 }
@@ -1655,6 +1713,10 @@ ConfigManager::run()
 
   m_started.set(m_facade->ownId());
 
+  // exclude nowait-nodes from config change protcol
+  m_all_mgm.bitANDC(m_opts.nowait_nodes);
+  m_all_mgm.set(m_facade->ownId()); // Never exclude own node
+
   start_checkers();
 
   while (!is_stopped())

=== modified file 'storage/ndb/src/mgmsrv/MgmtSrvr.hpp'
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp	2009-11-08 12:52:27 +0000
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp	2009-11-13 11:24:05 +0000
@@ -123,6 +123,7 @@ public:
     MgmtOpts() : configdir(MYSQLCLUSTERDIR) {};
     int reload;
     int initial;
+    NodeBitmask nowait_nodes;
   };
 
   MgmtSrvr(); // Not implemented

=== modified file 'storage/ndb/src/mgmsrv/main.cpp'
--- a/storage/ndb/src/mgmsrv/main.cpp	2009-09-25 07:27:49 +0000
+++ b/storage/ndb/src/mgmsrv/main.cpp	2009-11-13 11:24:05 +0000
@@ -85,6 +85,7 @@ bool g_RestartServer= false;
 static MgmtSrvr* mgm;
 static MgmtSrvr::MgmtOpts opts;
 static const char* opt_logname = "MgmtSrvr";
+static const char* opt_nowait_nodes = 0;
 
 static struct my_option my_long_options[] =
 {
@@ -142,6 +143,10 @@ static struct my_option my_long_options[
     "Name to use when logging messages for this node",
     (uchar**) &opt_logname, (uchar**) &opt_logname, 0,
     GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+  { "nowait-nodes", 256,
+    "Nodes that will not be waited for during start",
+    (uchar**) &opt_nowait_nodes, (uchar**) &opt_nowait_nodes, 0,
+    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
@@ -221,6 +226,24 @@ static int mgmd_main(int argc, char** ar
     mgmd_exit(1);
   }
 
+
+  if (opt_nowait_nodes)
+  {
+    int res = opts.nowait_nodes.parseMask(opt_nowait_nodes);
+    if(res == -2 || (res > 0 && opts.nowait_nodes.get(0)))
+    {
+      g_eventLogger->error("Invalid nodeid specified in nowait-nodes: '%s'",
+                           opt_nowait_nodes);
+      mgmd_exit(1);
+    }
+    else if (res < 0)
+    {
+      g_eventLogger->error("Unable to parse nowait-nodes argument: '%s'",
+                           opt_nowait_nodes);
+      mgmd_exit(1);
+    }
+  }
+
   /**
      Install signal handler for SIGPIPE
      Done in TransporterFacade as well.. what about Configretriever?

=== modified file 'storage/ndb/src/mgmsrv/testConfig.cpp'
--- a/storage/ndb/src/mgmsrv/testConfig.cpp	2009-11-03 16:40:26 +0000
+++ b/storage/ndb/src/mgmsrv/testConfig.cpp	2009-11-17 18:13:29 +0000
@@ -260,6 +260,40 @@ print_restart_info(void)
   fprintf(stderr, "\n");
 }
 
+
+static void
+checksum_config(void)
+{
+  Config* c1=
+    create_config("[ndbd]", "NoOfReplicas=1",
+                  "[ndb_mgmd]", "HostName=localhost",
+                  "[mysqld]", NULL);
+  Config* c2=
+    create_config("[ndbd]", "NoOfReplicas=1",
+                  "[ndb_mgmd]", "HostName=localhost",
+                  "[mysqld]", "[mysqld]", NULL);
+
+  ndbout_c("== checksum tests ==");
+  Uint32 c1_check = c1->checksum();
+  Uint32 c2_check = c2->checksum();
+  ndbout_c("c1->checksum(): 0x%x", c1_check);
+  ndbout_c("c2->checksum(): 0x%x", c2_check);
+   // Different config should not have same checksum
+  CHECK(c1_check != c2_check);
+
+  // Same config should have same checksum
+  CHECK(c1_check == c1->checksum());
+
+  // Copied config should have same checksum
+  Config c1_copy(c1);
+  CHECK(c1_check == c1_copy.checksum());
+
+  ndbout_c("==================");
+
+  delete c1;
+  delete c2;
+}
+
 #include <NdbTap.hpp>
 
 TAPTEST(MgmConfig)
@@ -267,6 +301,7 @@ TAPTEST(MgmConfig)
   ndb_init();
   diff_config();
   CHECK(check_params());
+  checksum_config();
 #if 0
   print_restart_info();
 #endif

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2009-09-04 11:33:38 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2009-11-18 11:05:02 +0000
@@ -2432,7 +2432,17 @@ NdbDictInterface::execGET_TABINFO_REF(Nd
   const GetTabInfoRef* ref = CAST_CONSTPTR(GetTabInfoRef, 
 					   signal->getDataPtr());
   
-  m_error.code= ref->errorCode;
+  if (likely(signal->getLength() == GetTabInfoRef::SignalLength))
+  {
+    m_error.code= ref->errorCode;
+  }
+  else
+  {
+    /* 6.3 <-> 7.0 upgrade only */
+    assert (signal->getLength() == GetTabInfoRef::OriginalSignalLength);
+    m_error.code = (*(signal->getDataPtr() + 
+                      GetTabInfoRef::OriginalErrorOffset));
+  }
   m_waiter.signal(NO_WAIT);
 }
 
@@ -4713,7 +4723,18 @@ NdbDictInterface::execSUB_START_CONF(Ndb
   }
   }
 
-  m_sub_start_conf.m_buckets = subStartConf->bucketCount;
+  if (signal->getLength() == SubStartConf::SignalLength)
+  {
+    m_sub_start_conf.m_buckets = subStartConf->bucketCount;
+  }
+  else
+  {
+    /* 6.3 <-> 7.0 upgrade 
+     * 6.3 doesn't send required bucketCount.  
+     * ~0 indicates no bucketCount received
+     */
+    m_sub_start_conf.m_buckets = ~0;
+  }
   DBUG_PRINT("info",("subscriptionId=%d,subscriptionKey=%d,subscriberData=%d",
 		     subscriptionId,subscriptionKey,subscriberData));
   m_waiter.signal(NO_WAIT);
@@ -7758,6 +7779,13 @@ NdbDictionaryImpl::beginSchemaTrans()
     m_error.code = 4410;
     DBUG_RETURN(-1);
   }
+  if (!m_receiver.checkAllNodeVersionsMin(NDBD_SCHEMA_TRANS_VERSION))
+  {
+    /* Upgrade 6.3 -> 7.0 path */
+    /* Schema transaction not possible until upgrade complete */
+    m_error.code = 4411;
+    DBUG_RETURN(-1);
+  }
   // TODO real transId
   m_tx.m_transId = rand();
   m_tx.m_state = NdbDictInterface::Tx::Started;
@@ -7839,6 +7867,27 @@ committed:
   DBUG_RETURN(0);
 }
 
+bool
+NdbDictInterface::checkAllNodeVersionsMin(Uint32 minNdbVersion) const
+{
+  for (Uint32 nodeId = 1; nodeId < MAX_NODES; nodeId++)
+  {
+    if (m_transporter->getIsDbNode(nodeId) &&
+        m_transporter->getIsNodeSendable(nodeId) &&
+        (m_transporter->getNodeNdbVersion(nodeId) <
+         minNdbVersion))
+    {
+      /* At least 1 sendable data node has lower-than-min
+       * version
+       */
+      return false;
+    }
+  }
+  
+  return true;
+}
+
+
 int
 NdbDictInterface::beginSchemaTrans()
 {

=== modified file 'storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2009-09-04 11:33:38 +0000
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp	2009-11-18 11:05:02 +0000
@@ -689,6 +689,8 @@ public:
   int endSchemaTrans(Uint32 flags);
   Tx & m_tx; // shared with NdbDictionaryImpl
 
+  bool checkAllNodeVersionsMin(Uint32 minNdbVersion) const;
+
   const NdbError &getNdbError() const;  
   NdbError & m_error;
 private:

=== modified file 'storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp'
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp	2009-08-06 13:51:18 +0000
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp	2009-11-18 13:13:34 +0000
@@ -616,6 +616,12 @@ NdbEventOperationImpl::execute_nolock()
                                                                    buckets);
   if (r == 0) 
   {
+    /* Pre-7.0 kernel nodes do not return the number of buckets
+     * Assume it's == theNoOfDBnodes as was the case in 6.3
+     */
+    if (buckets == ~ (Uint32)0)
+      buckets = m_ndb->theImpl->theNoOfDBnodes;
+
     m_ndb->theEventBuffer->set_total_buckets(buckets);
 
     if (theMainOp == NULL) {

=== modified file 'storage/ndb/src/ndbapi/NdbImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbImpl.hpp	2009-09-30 06:58:07 +0000
+++ b/storage/ndb/src/ndbapi/NdbImpl.hpp	2009-11-18 11:05:02 +0000
@@ -110,6 +110,14 @@ public:
     return;
   }
 
+  bool forceShortRequests;
+
+  static inline void setForceShortRequests(Ndb* ndb, bool val)
+  {
+    ndb->theImpl->forceShortRequests = val;
+  }
+
+
   BaseString m_systemPrefix; // Buffer for preformatted for <sys>/<def>/
 
   /**

=== modified file 'storage/ndb/src/ndbapi/NdbOperationExec.cpp'
--- a/storage/ndb/src/ndbapi/NdbOperationExec.cpp	2009-10-06 11:19:40 +0000
+++ b/storage/ndb/src/ndbapi/NdbOperationExec.cpp	2009-11-18 11:05:02 +0000
@@ -130,6 +130,128 @@ NdbOperation::setLastFlag(NdbApiSignal* 
   TcKeyReq::setExecuteFlag(req->requestInfo, lastFlag);
 }
 
+int
+NdbOperation::doSendKeyReq(int aNodeId, 
+                           GenericSectionPtr* secs, 
+                           Uint32 numSecs)
+{
+  /* Send a KeyRequest - could be TCKEYREQ or TCINDXREQ
+   *
+   * Normally we send a single long signal with 1 or 2
+   * sections containing KeyInfo and AttrInfo.
+   * For backwards compatibility and testing purposes 
+   * we can send signal trains instead.
+   */
+  NdbApiSignal* request = theTCREQ;
+  TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
+  Uint32 tcNodeVersion = tp->getNodeNdbVersion(aNodeId);
+  bool forceShort = false;
+  forceShort = theNdb->theImpl->forceShortRequests;
+  bool sendLong = ( tcNodeVersion >= NDBD_LONG_TCKEYREQ ) &&
+    ! forceShort;
+  
+  if (sendLong)
+  {
+    return tp->sendSignal(request, aNodeId, secs, numSecs);
+  }
+  else
+  {
+    /* Send signal as short request - either for backwards
+     * compatibility or testing
+     */
+    Uint32 sigCount = 1;
+    Uint32 keyInfoLen  = secs[0].sz;
+    Uint32 attrInfoLen = (numSecs == 2)?
+      secs[1].sz : 
+      0;
+    
+    Uint32 keyInfoInReq = MIN(keyInfoLen, TcKeyReq::MaxKeyInfo);
+    Uint32 attrInfoInReq = MIN(attrInfoLen, TcKeyReq::MaxAttrInfo);
+    TcKeyReq* tcKeyReq = (TcKeyReq*) request->getDataPtrSend();
+    Uint32 connectPtr = tcKeyReq->apiConnectPtr;
+    Uint32 transId1 = tcKeyReq->transId1;
+    Uint32 transId2 = tcKeyReq->transId2;
+    bool indexReq = (request->theVerId_signalNumber == GSN_TCINDXREQ);
+    
+    Uint32 reqLen = request->theLength;
+    
+    /* Set TCKEYREQ flags */
+    TcKeyReq::setKeyLength(tcKeyReq->requestInfo, keyInfoLen);
+    TcKeyReq::setAIInTcKeyReq(tcKeyReq->requestInfo , attrInfoInReq);
+    TcKeyReq::setAttrinfoLen(tcKeyReq->attrLen, attrInfoLen);
+    
+    Uint32* writePtr = request->getDataPtrSend() + reqLen;
+
+    GSIReader keyInfoReader(secs[0].sectionIter);
+    GSIReader attrInfoReader(secs[1].sectionIter);
+    
+    keyInfoReader.copyNWords(writePtr, keyInfoInReq);
+    writePtr += keyInfoInReq;
+    attrInfoReader.copyNWords(writePtr, attrInfoInReq);
+
+    reqLen += keyInfoInReq + attrInfoInReq;
+    assert( reqLen <= TcKeyReq::SignalLength );
+
+    request->setLength(reqLen);
+
+    if (tp->sendSignal(request, aNodeId) == -1)
+      return -1;
+    
+    keyInfoLen -= keyInfoInReq;
+    attrInfoLen -= attrInfoInReq;
+
+    if (keyInfoLen)
+    {
+      request->theVerId_signalNumber = indexReq ? 
+        GSN_INDXKEYINFO : GSN_KEYINFO;
+      KeyInfo* keyInfo = (KeyInfo*) request->getDataPtrSend();
+      keyInfo->connectPtr = connectPtr;
+      keyInfo->transId[0] = transId1;
+      keyInfo->transId[1] = transId2;
+
+      while(keyInfoLen)
+      {
+        Uint32 dataWords = MIN(keyInfoLen, KeyInfo::DataLength);
+
+        keyInfoReader.copyNWords(&keyInfo->keyData[0], dataWords);
+        request->setLength(KeyInfo::HeaderLength + dataWords);
+
+        if (tp->sendSignal(request, aNodeId) == -1)
+          return -1;
+
+        keyInfoLen-= dataWords;
+        sigCount++;
+      }
+    }
+
+    if (attrInfoLen)
+    {
+      request->theVerId_signalNumber = indexReq ? 
+        GSN_INDXATTRINFO : GSN_ATTRINFO;
+      AttrInfo* attrInfo = (AttrInfo*) request->getDataPtrSend();
+      attrInfo->connectPtr = connectPtr;
+      attrInfo->transId[0] = transId1;
+      attrInfo->transId[1] = transId2;
+
+      while(attrInfoLen)
+      {
+        Uint32 dataWords = MIN(attrInfoLen, AttrInfo::DataLength);
+
+        attrInfoReader.copyNWords(&attrInfo->attrData[0], dataWords);
+        request->setLength(AttrInfo::HeaderLength + dataWords);
+
+        if (tp->sendSignal(request, aNodeId) == -1)
+          return -1;
+
+        attrInfoLen-= dataWords;
+        sigCount++;
+      }
+    }
+    
+    return sigCount;
+  }
+}
+
 /******************************************************************************
 int doSend()
 
@@ -144,17 +266,40 @@ NdbOperation::doSend(int aNodeId, Uint32
 {
   assert(theTCREQ != NULL);
   setLastFlag(theTCREQ, lastFlag);
+  Uint32 numSecs= 1;
+  GenericSectionPtr secs[2];
 
   if (m_attribute_record != NULL)
   {
-    /* NdbRecord send - single long signal */
-    if (doSendNdbRecord(aNodeId) == -1 )
+    /*
+     * NdbRecord signal building code puts all KeyInfo and 
+     * AttrInfo into the KeyInfo and AttrInfo signal lists.
+     */
+    SignalSectionIterator keyInfoIter(theTCREQ->next());
+    SignalSectionIterator attrInfoIter(theFirstATTRINFO);
+    
+    /* KeyInfo - always present for TCKEY/INDXREQ*/
+    secs[0].sz= theTupKeyLen;
+    secs[0].sectionIter= &keyInfoIter;
+    
+    /* AttrInfo - not always needed (e.g. Delete) */
+    if (theTotalCurrAI_Len != 0)
+    {
+      secs[1].sz= theTotalCurrAI_Len;
+      secs[1].sectionIter= &attrInfoIter;
+      numSecs++;
+    }
+    
+    if (doSendKeyReq(aNodeId, &secs[0], numSecs) == -1)
       return -1;
   }
   else
   {
-    /* Old Api send - transform signal train to long sections */
-    TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
+    /* 
+     * Old Api signal building code puts first words of KeyInfo
+     * and AttrInfo into the initial request signal
+     * We use special iterators to extract this
+     */
 
     TcKeyReq* tcKeyReq= (TcKeyReq*) theTCREQ->getDataPtrSend();
     const Uint32 inlineKIOffset= Uint32(tcKeyReq->keyInfo - (Uint32*)tcKeyReq);
@@ -164,8 +309,6 @@ NdbOperation::doSend(int aNodeId, Uint32
     const Uint32 inlineAILength= MIN(TcKeyReq::MaxAttrInfo, 
                                      theTotalCurrAI_Len);
     
-    Uint32 numSecs= 1;
-    GenericSectionPtr secs[2];
     /* Create iterators which use the signal train to extract
      * long sections from the short signal trains
      */
@@ -190,7 +333,7 @@ NdbOperation::doSend(int aNodeId, Uint32
       numSecs++;
     }
 
-    if (tp->sendSignal(theTCREQ, aNodeId, &secs[0], numSecs) == -1)
+    if (doSendKeyReq(aNodeId, &secs[0], numSecs) == -1)
       return -1;
   }
 
@@ -204,36 +347,6 @@ NdbOperation::doSend(int aNodeId, Uint32
 }//NdbOperation::doSend()
 
 
-int
-NdbOperation::doSendNdbRecord(int aNodeId)
-{
- /*
-  * Send a long signal to the kernel.
-  * KeyInfo and AttrInfo for NdbRecord are always sent as
-  * separate sections, with none in the TCKEYREQ
-  */
-  TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
-
-  Uint32 numSecs= 1;
-  GenericSectionPtr secs[2];
-  SignalSectionIterator keyInfoIter(theTCREQ->next());
-  SignalSectionIterator attrInfoIter(theFirstATTRINFO);
-  
-  /* KeyInfo - always present for TCKEY/INDXREQ*/
-  secs[0].sz= theTupKeyLen;
-  secs[0].sectionIter= &keyInfoIter;
-
-  /* AttrInfo - not always needed (e.g. Delete) */
-  if (theTotalCurrAI_Len != 0)
-  {
-    secs[1].sz= theTotalCurrAI_Len;
-    secs[1].sectionIter= &attrInfoIter;
-    numSecs++;
-  }
-
-  return tp->sendSignal(theTCREQ, aNodeId, &secs[0], numSecs);
-}
-
 /***************************************************************************
 int prepareSend(Uint32 aTC_ConnectPtr,
                 Uint64 aTransactionId)

=== modified file 'storage/ndb/src/ndbapi/NdbScanOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp	2009-09-30 07:59:42 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp	2009-11-18 11:05:02 +0000
@@ -2420,15 +2420,93 @@ NdbScanOperation::doSendScan(int aProces
   }
 
   TransporterFacade *tp = theNdb->theImpl->m_transporter_facade;
-  
-  /* Send Fragmented as SCAN_TABREQ can be large */
-  if (tp->sendFragmentedSignal(theSCAN_TABREQ, 
-                               aProcessorId, 
-                               &secs[0], 
-                               numSections) == -1)
+
+  Uint32 tcNodeVersion = tp->getNodeNdbVersion(aProcessorId);
+  bool forceShort = false;
+  forceShort = theNdb->theImpl->forceShortRequests;
+  bool sendLong = ( tcNodeVersion >= NDBD_LONG_SCANTABREQ) &&
+    ! forceShort;
+  
+  if (sendLong)
+  {
+    /* Send Fragmented as SCAN_TABREQ can be large */
+    if (tp->sendFragmentedSignal(theSCAN_TABREQ, 
+                                 aProcessorId, 
+                                 &secs[0], 
+                                 numSections) == -1)
+    {
+      setErrorCode(4002);
+      return -1;
+    }
+  }
+  else
   {
-    setErrorCode(4002);
-    return -1;
+    /* Send a 'short' SCANTABREQ - e.g. long SCANTABREQ
+     * with signalIds as first section, followed by
+     * AttrInfo and KeyInfo trains
+     */
+    Uint32 attrInfoLen = secs[1].sz;
+    Uint32 keyInfoLen = (numSections == 3)? secs[2].sz : 0;
+
+    ScanTabReq* scanTabReq = (ScanTabReq*) theSCAN_TABREQ->getDataPtrSend();
+    Uint32 connectPtr = scanTabReq->apiConnectPtr;
+    Uint32 transId1 = scanTabReq->transId1;
+    Uint32 transId2 = scanTabReq->transId2;
+
+    /* Modify ScanTabReq to carry length of keyinfo and attrinfo */
+    scanTabReq->attrLenKeyLen = (keyInfoLen << 16) | attrInfoLen;
+
+    /* Send with receiver Ids as first and only section */
+    if (tp->sendSignal(theSCAN_TABREQ, aProcessorId, &secs[0], 1) == -1)
+    {
+      setErrorCode(4002);
+      return -1;
+    }
+
+    if (keyInfoLen)
+    {
+      GSIReader keyInfoReader(secs[2].sectionIter);
+      theSCAN_TABREQ->theVerId_signalNumber = GSN_KEYINFO;
+      KeyInfo* keyInfo = (KeyInfo*) theSCAN_TABREQ->getDataPtrSend();
+      keyInfo->connectPtr = connectPtr;
+      keyInfo->transId[0] = transId1;
+      keyInfo->transId[1] = transId2;
+
+      while(keyInfoLen)
+      {
+        Uint32 dataWords = MIN(keyInfoLen, KeyInfo::DataLength);
+        keyInfoReader.copyNWords(&keyInfo->keyData[0], dataWords);
+        theSCAN_TABREQ->setLength(KeyInfo::HeaderLength + dataWords);
+
+        if (tp->sendSignal(theSCAN_TABREQ, aProcessorId) == -1)
+        {
+          setErrorCode(4002);
+          return -1;
+        }
+        keyInfoLen -= dataWords;
+      }
+    }
+
+    GSIReader attrInfoReader(secs[1].sectionIter);
+    theSCAN_TABREQ->theVerId_signalNumber = GSN_ATTRINFO;
+    AttrInfo* attrInfo = (AttrInfo*) theSCAN_TABREQ->getDataPtrSend();
+    attrInfo->connectPtr = connectPtr;
+    attrInfo->transId[0] = transId1;
+    attrInfo->transId[1] = transId2;
+    
+    while(attrInfoLen)
+    {
+      Uint32 dataWords = MIN(attrInfoLen, AttrInfo::DataLength);
+      attrInfoReader.copyNWords(&attrInfo->attrData[0], dataWords);
+      theSCAN_TABREQ->setLength(AttrInfo::HeaderLength + dataWords);
+
+      if (tp->sendSignal(theSCAN_TABREQ, aProcessorId) == -1)
+      {
+        setErrorCode(4002);
+        return -1;
+      }
+      attrInfoLen -= dataWords;
+    }
   }
 
   theStatus = WaitResponse;  

=== modified file 'storage/ndb/src/ndbapi/Ndbinit.cpp'
--- a/storage/ndb/src/ndbapi/Ndbinit.cpp	2009-05-26 18:53:34 +0000
+++ b/storage/ndb/src/ndbapi/Ndbinit.cpp	2009-11-18 11:05:02 +0000
@@ -219,6 +219,11 @@ NdbImpl::NdbImpl(Ndb_cluster_connection 
 
   m_systemPrefix.assfmt("%s%c%s%c", NDB_SYSTEM_DATABASE, table_name_separator,
 			NDB_SYSTEM_SCHEMA, table_name_separator);
+
+  forceShortRequests = false;
+  const char* f= getenv("NDB_FORCE_SHORT_REQUESTS");
+  if (f != 0 && *f != 0 && *f != '0' && *f != 'n' && *f != 'N')
+    forceShortRequests = true;
 }
 
 NdbImpl::~NdbImpl()

=== modified file 'storage/ndb/src/ndbapi/TransporterFacade.hpp'
--- a/storage/ndb/src/ndbapi/TransporterFacade.hpp	2009-07-03 06:34:01 +0000
+++ b/storage/ndb/src/ndbapi/TransporterFacade.hpp	2009-11-18 11:05:02 +0000
@@ -95,6 +95,7 @@ public:
   bool   getIsNodeSendable(NodeId nodeId) const;
   Uint32 getNodeGrp(NodeId nodeId) const;
   Uint32 getNodeSequence(NodeId nodeId) const;
+  Uint32 getNodeNdbVersion(NodeId nodeId) const;
 
   // Is there space in sendBuffer to send messages
   bool   check_send_size(Uint32 node_id, Uint32 send_size);
@@ -439,6 +440,13 @@ TransporterFacade::getNodeSequence(NodeI
 
 inline
 Uint32
+TransporterFacade::getNodeNdbVersion(NodeId n) const
+{
+  return theClusterMgr->getNodeInfo(n).m_info.m_version;
+}
+
+inline
+Uint32
 TransporterFacade::get_scan_batch_size() {
   return m_scan_batch_size;
 }
@@ -534,4 +542,57 @@ public :
   Uint32* getNextWords(Uint32& sz);
 };
 
+/*
+ * GenericSectionIteratorReader
+ * Helper class to simplify reading data from 
+ * GenericSectionIterator implementations
+ */
+
+class GSIReader
+{
+private :
+  GenericSectionIterator* gsi;
+  const Uint32* chunkPtr;
+  Uint32 chunkRemain;
+public :
+  GSIReader(GenericSectionIterator* _gsi)
+  {
+    gsi = _gsi;
+    chunkPtr = NULL;
+    chunkRemain = 0;
+  }
+
+  void copyNWords(Uint32* dest, Uint32 n)
+  {
+    while (n)
+    {
+      if (chunkRemain == 0)
+      {
+        /* Get next contiguous stretch of words from
+         * the iterator
+         */
+        chunkPtr = gsi->getNextWords(chunkRemain);
+        if (!chunkRemain)
+          abort(); // Must have the words the caller asks for
+      }
+      else
+      {
+        /* Have some words from the iterator, copy some/
+         * all of them
+         */
+        Uint32 wordsToCopy = MIN(chunkRemain, n);
+        memcpy(dest, chunkPtr, wordsToCopy << 2);
+        chunkPtr += wordsToCopy;
+        chunkRemain -= wordsToCopy;
+
+        dest += wordsToCopy;
+        n -= wordsToCopy;
+      }
+    }
+  }
+};
+
+  
+
+
 #endif // TransporterFacade_H

=== modified file 'storage/ndb/src/ndbapi/ndb_cluster_connection.cpp'
--- a/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp	2009-09-08 15:12:34 +0000
+++ b/storage/ndb/src/ndbapi/ndb_cluster_connection.cpp	2009-11-17 16:26:09 +0000
@@ -290,7 +290,6 @@ Ndb_cluster_connection_impl(const char *
   : Ndb_cluster_connection(*this),
     m_main_connection(main_connection),
     m_optimized_node_selection(1),
-    m_name(0),
     m_run_connect_thread(0),
     m_latest_trans_gci(0),
     m_first_ndb_object(0),
@@ -335,13 +334,6 @@ Ndb_cluster_connection_impl(const char *
       ("Could not initialize handle to management server: %s",
        m_config_retriever->getErrorString());
     printf("%s\n", get_latest_error_msg());
-    delete m_config_retriever;
-    m_config_retriever= 0;
-  }
-  if (m_name)
-  {
-    NdbMgmHandle h= m_config_retriever->get_mgmHandle();
-    ndb_mgm_set_name(h, m_name);
   }
   if (!m_main_connection)
   {
@@ -354,6 +346,11 @@ Ndb_cluster_connection_impl(const char *
     m_globalDictCache = 0;
     m_transporter_facade=
       new TransporterFacade(m_main_connection->m_impl.m_globalDictCache);
+
+    // The secondary connection can't use same nodeid, clear the nodeid
+    // in ConfigRetriver to avoid asking for the same nodeid again
+    m_config_retriever->setNodeId(0);
+
   }
 
   DBUG_VOID_RETURN;
@@ -395,8 +392,6 @@ Ndb_cluster_connection_impl::~Ndb_cluste
     ndb_print_state_mutex= NULL;
   }
 #endif
-  if (m_name)
-    free(m_name);
 
   NdbMutex_Lock(g_ndb_connection_mutex);
   if(--g_ndb_connection_count == 0)
@@ -483,14 +478,8 @@ Ndb_cluster_connection_impl::unlink_ndb_
 void
 Ndb_cluster_connection_impl::set_name(const char *name)
 {
-  if (m_name)
-    free(m_name);
-  m_name= strdup(name);
-  if (m_config_retriever && m_name)
-  {
-    NdbMgmHandle h= m_config_retriever->get_mgmHandle();
-    ndb_mgm_set_name(h, m_name);
-  }
+  NdbMgmHandle h= m_config_retriever->get_mgmHandle();
+  ndb_mgm_set_name(h, name);
 }
 
 int

=== modified file 'storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp'
--- a/storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp	2009-11-17 16:15:19 +0000
@@ -89,7 +89,6 @@ private:
   int (*m_connect_callback)(void);
 
   int m_optimized_node_selection;
-  char *m_name;
   int m_run_connect_thread;
   NdbMutex *m_event_add_drop_mutex;
   Uint64 m_latest_trans_gci;

=== modified file 'storage/ndb/src/ndbapi/ndberror.c'
--- a/storage/ndb/src/ndbapi/ndberror.c	2009-11-09 13:29:20 +0000
+++ b/storage/ndb/src/ndbapi/ndberror.c	2009-11-18 11:05:02 +0000
@@ -582,6 +582,7 @@ ErrorBundle ErrorCodes[] = {
   { 4401, DMEC, AE, "Only one schema operation per schema transaction" },
   { 4402, DMEC, AE, "No schema operation defined before calling execute" },
   { 4410, DMEC, AE, "Schema transaction is already started" },
+  { 4411, DMEC, AE, "Schema transaction not possible until upgrade complete" },
 
   { 4501, DMEC, AE, "Insert in hash table failed when getting table information from Ndb" },
   { 4502, DMEC, AE, "GetValue not allowed in Update operation" },

=== modified file 'storage/ndb/test/include/NDBT_Test.hpp'
--- a/storage/ndb/test/include/NDBT_Test.hpp	2009-09-16 12:40:24 +0000
+++ b/storage/ndb/test/include/NDBT_Test.hpp	2009-11-18 11:05:02 +0000
@@ -380,6 +380,8 @@ public:
   void setLogging(bool val);
   bool getLogging() const;
 
+  bool getForceShort() const;
+
   int createTables(Ndb_cluster_connection&) const;
   int dropTables(Ndb_cluster_connection&) const;
 
@@ -417,6 +419,7 @@ private:
   bool m_logging;
   NDBT_DriverType m_driverType;
   bool m_noddl;
+  bool m_forceShort;
 };
 
 

=== modified file 'storage/ndb/test/ndbapi/testMgmd.cpp'
--- a/storage/ndb/test/ndbapi/testMgmd.cpp	2009-10-06 12:17:23 +0000
+++ b/storage/ndb/test/ndbapi/testMgmd.cpp	2009-11-17 18:13:29 +0000
@@ -613,6 +613,176 @@ int runTestBug42015(NDBT_Context* ctx, N
 
 }
 
+int runTestNowaitNodes(NDBT_Context* ctx, NDBT_Step* step)
+{
+  MgmdProcessList mgmds;
+  NDBT_Workingdir wd("test_mgmd"); // temporary working directory
+
+  // Create config.ini
+  Properties config = ConfigFactory::create(2);
+  CHECK(ConfigFactory::write_config_ini(config,
+                                        path(wd.path(),
+                                             "config.ini",
+                                             NULL).c_str()));
+  // Start first ndb_mgmd
+  {
+    Mgmd* mgmd1 = new Mgmd(1);
+    CHECK(mgmd1->start_from_config_ini(wd.path(),
+                                    "--initial",
+                                       "--nowait-nodes=2",
+                                       NULL));
+    mgmds.push_back(mgmd1);
+
+    // Connect the ndb_mgmd
+    CHECK(mgmd1->connect(config));
+
+    // wait for confirmed config
+    CHECK(mgmd1->wait_confirmed_config());
+
+    // Check binary config file created
+    CHECK(file_exists(path(wd.path(),
+                           "ndb_1_config.bin.1",
+                           NULL).c_str()));
+  }
+
+  // Start second ndb_mgmd
+  {
+    Mgmd* mgmd2 = new Mgmd(2);
+    CHECK(mgmd2->start_from_config_ini(wd.path(),
+                                       "--initial",
+                                       NULL));
+    mgmds.push_back(mgmd2);
+
+    // Connect the ndb_mgmd
+    CHECK(mgmd2->connect(config));
+
+    // wait for confirmed config
+    CHECK(mgmd2->wait_confirmed_config());
+
+    // Check binary config file created
+    CHECK(file_exists(path(wd.path(),
+                           "ndb_2_config.bin.1",
+                           NULL).c_str()));
+
+  }
+
+  // Create new config.ini
+  g_err << "** Create config2.ini" << endl;
+  CHECK(ConfigFactory::put(config, "ndb_mgmd", 1, "ArbitrationDelay", 100));
+  CHECK(ConfigFactory::write_config_ini(config,
+                                        path(wd.path(),
+                                             "config2.ini",
+                                             NULL).c_str()));
+
+  g_err << "** Reload second mgmd from config2.ini" << endl;
+  {
+    Mgmd* mgmd2 = mgmds[1];
+    CHECK(mgmd2->stop());
+    // Start from config2.ini
+    CHECK(mgmd2->start_from_config_ini(wd.path(),
+                                       "-f config2.ini",
+                                       "--reload", NULL));
+    CHECK(mgmd2->connect(config));
+    CHECK(mgmd2->wait_confirmed_config());
+
+    CHECK(file_exists(path(wd.path(),
+                           "ndb_1_config.bin.1",
+                           NULL).c_str()));
+    CHECK(file_exists(path(wd.path(),
+                           "ndb_2_config.bin.1",
+                           NULL).c_str()));
+
+    // Both ndb_mgmd(s) should have reloaded and new binary config exist
+    CHECK(file_exists(path(wd.path(),
+                           "ndb_1_config.bin.2",
+                           NULL).c_str()));
+    CHECK(file_exists(path(wd.path(),
+                           "ndb_2_config.bin.2",
+                           NULL).c_str()));
+  }
+
+  // Stop the ndb_mgmd(s)
+  for (unsigned i = 0; i < mgmds.size(); i++)
+    CHECK(mgmds[i]->stop());
+
+  return NDBT_OK;
+}
+
+
+int runTestNowaitNodes2(NDBT_Context* ctx, NDBT_Step* step)
+{
+  int ret;
+  NDBT_Workingdir wd("test_mgmd"); // temporary working directory
+
+  // Create config.ini
+  Properties config = ConfigFactory::create(2);
+  CHECK(ConfigFactory::write_config_ini(config,
+                                        path(wd.path(),
+                                             "config.ini",
+                                             NULL).c_str()));
+
+  g_err << "** Start mgmd1 from config.ini" << endl;
+  Mgmd* mgmd1 = new Mgmd(1);
+  CHECK(mgmd1->start_from_config_ini(wd.path(),
+                                     "--initial",
+                                     "--nowait-nodes=1-255",
+                                     NULL));
+  CHECK(mgmd1->connect(config));
+  CHECK(mgmd1->wait_confirmed_config());
+
+  // check config files exist
+  CHECK(file_exists(path(wd.path(),
+                         "ndb_1_config.bin.1",
+                         NULL).c_str()));
+
+  g_err << "** Create config2.ini" << endl;
+  CHECK(ConfigFactory::put(config, "ndb_mgmd", 1, "ArbitrationDelay", 100));
+  CHECK(ConfigFactory::write_config_ini(config,
+                                        path(wd.path(),
+                                             "config2.ini",
+                                             NULL).c_str()));
+
+  g_err << "** Start mgmd2 from config2.ini" << endl;
+  Mgmd* mgmd2 = new Mgmd(2);
+  CHECK(mgmd2->start_from_config_ini(wd.path(),
+                                     "-f config2.ini",
+                                     "--initial",
+                                     "--nowait-nodes=1-255",
+                                     NULL));
+  CHECK(mgmd2->wait(ret));
+  CHECK(ret == 1);
+
+  CHECK(mgmd1->stop());
+
+  g_err << "** Start mgmd2 again from config2.ini" << endl;
+  CHECK(mgmd2->start_from_config_ini(wd.path(),
+                                     "-f config2.ini",
+                                     "--initial",
+                                     "--nowait-nodes=1-255",
+                                     NULL));
+
+
+  CHECK(mgmd2->connect(config));
+  CHECK(mgmd2->wait_confirmed_config());
+
+  // check config files exist
+  CHECK(file_exists(path(wd.path(),
+                         "ndb_2_config.bin.1",
+                         NULL).c_str()));
+
+  g_err << "** Start mgmd1 from config.ini, mgmd2 should shutdown" << endl;
+  CHECK(mgmd1->start_from_config_ini(wd.path(),
+                                     "--initial",
+                                     "--nowait-nodes=1-255",
+                                     NULL));
+  CHECK(mgmd2->wait(ret));
+  CHECK(ret == 1);
+
+  CHECK(mgmd1->stop());
+
+  return NDBT_OK;
+}
+
 NDBT_TESTSUITE(testMgmd);
 DRIVER(DummyDriver); /* turn off use of NdbApi */
 
@@ -633,6 +803,19 @@ TESTCASE("Bug42015",
 {
   INITIALIZER(runTestBug42015);
 }
+TESTCASE("NowaitNodes",
+         "Test that one mgmd(of 2) can start alone with usage "
+         "of --nowait-nodes, then start the second mgmd and it should join")
+{
+  INITIALIZER(runTestNowaitNodes);
+}
+TESTCASE("NowaitNodes2",
+         "Test that one mgmd(of 2) can start alone with usage "
+         "of --nowait-nodes, then start the second mgmd from different "
+         "configuration and the one with lowest nodeid should shutdown")
+{
+  INITIALIZER(runTestNowaitNodes2);
+}
 
 NDBT_TESTSUITE_END(testMgmd);
 

=== modified file 'storage/ndb/test/ndbapi/testNdbinfo.cpp'
--- a/storage/ndb/test/ndbapi/testNdbinfo.cpp	2009-11-08 12:52:27 +0000
+++ b/storage/ndb/test/ndbapi/testNdbinfo.cpp	2009-11-17 16:55:50 +0000
@@ -20,6 +20,7 @@
 #include <NDBT_Test.hpp>
 #include "../../src/ndbapi/NdbInfo.hpp"
 
+#include <NdbRestarter.hpp>
 
 int runTestNdbInfo(NDBT_Context* ctx, NDBT_Step* step)
 {
@@ -121,10 +122,10 @@ int runScanAll(NDBT_Context* ctx, NDBT_S
         columnId++;
       // At least one column
       assert(columnId >= 1);
-
-      if(scanOp->execute() != 0)
+      int ret;
+      if((ret = scanOp->execute()) != 0)
       {
-        g_err << "scanOp->execute failed" << endl;
+        g_err << "scanOp->execute failed, ret: " << ret << endl;
         return NDBT_FAILED;
       }
 
@@ -143,6 +144,20 @@ int runScanAll(NDBT_Context* ctx, NDBT_S
   return NDBT_FAILED;
 }
 
+
+int runScanAllUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
+  int i = 0;
+  while (ctx->isTestStopped() == false) {
+    g_info << i << ": ";
+    if (runScanAll(ctx,  step) != NDBT_OK){
+      return NDBT_FAILED;
+    }
+    i++;
+  }
+  return NDBT_OK;
+}
+
+
 int runScanStop(NDBT_Context* ctx, NDBT_Step* step)
 {
   NdbInfo ndbinfo(&ctx->m_cluster_connection, "ndbinfo/");
@@ -372,6 +387,84 @@ int runTestTable(NDBT_Context* ctx, NDBT
   return NDBT_OK;
 }
 
+int runRestarter(NDBT_Context* ctx, NDBT_Step* step){
+  int result = NDBT_OK;
+  int loops = ctx->getNumLoops();
+  int sync_threads = ctx->getProperty("SyncThreads", (unsigned)0);
+  int sleep0 = ctx->getProperty("Sleep0", (unsigned)0);
+  int sleep1 = ctx->getProperty("Sleep1", (unsigned)0);
+  int randnode = ctx->getProperty("RandNode", (unsigned)0);
+  NdbRestarter restarter;
+  int i = 0;
+  int lastId = 0;
+
+  if (restarter.getNumDbNodes() < 2){
+    ctx->stopTest();
+    return NDBT_OK;
+  }
+
+  if(restarter.waitClusterStarted() != 0){
+    g_err << "Cluster failed to start" << endl;
+    return NDBT_FAILED;
+  }
+
+  loops *= (restarter.getNumDbNodes() > 2 ? 2 : restarter.getNumDbNodes());
+  if (loops < restarter.getNumDbNodes())
+    loops = restarter.getNumDbNodes();
+
+  while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){
+
+    int id = lastId % restarter.getNumDbNodes();
+    if (randnode == 1)
+    {
+      id = rand() % restarter.getNumDbNodes();
+    }
+    int nodeId = restarter.getDbNodeId(id);
+    ndbout << "Restart node " << nodeId << endl;
+    if(restarter.restartOneDbNode(nodeId, false, true, true) != 0){
+      g_err << "Failed to restartNextDbNode" << endl;
+      result = NDBT_FAILED;
+      break;
+    }
+
+    if (restarter.waitNodesNoStart(&nodeId, 1))
+    {
+      g_err << "Failed to waitNodesNoStart" << endl;
+      result = NDBT_FAILED;
+      break;
+    }
+
+    if (sleep1)
+      NdbSleep_MilliSleep(sleep1);
+
+    if (restarter.startNodes(&nodeId, 1))
+    {
+      g_err << "Failed to start node" << endl;
+      result = NDBT_FAILED;
+      break;
+    }
+
+    if(restarter.waitClusterStarted() != 0){
+      g_err << "Cluster failed to start" << endl;
+      result = NDBT_FAILED;
+      break;
+    }
+
+    if (sleep0)
+      NdbSleep_MilliSleep(sleep0);
+
+    ctx->sync_up_and_wait("PauseThreads", sync_threads);
+
+    lastId++;
+    i++;
+  }
+
+  ctx->stopTest();
+
+  return result;
+}
+
+
 
 NDBT_TESTSUITE(testNdbinfo);
 TESTCASE("Ndbinfo",
@@ -399,6 +492,13 @@ TESTCASE("TestTable",
           "of rows which will depend on how many TUP blocks are configured"){
   STEP(runTestTable);
 }
+#if 0
+TESTCASE("NodeRestart", "Scan NdbInfo tables while restarting nodes"){
+  TC_PROPERTY("Sleep0", 29000); // Between restarts
+  STEP(runRestarter);
+  STEPS(runScanAllUntilStopped, 1);
+}
+#endif
 NDBT_TESTSUITE_END(testNdbinfo);
 
 

=== modified file 'storage/ndb/test/ndbapi/testPartitioning.cpp'
--- a/storage/ndb/test/ndbapi/testPartitioning.cpp	2009-05-27 15:21:45 +0000
+++ b/storage/ndb/test/ndbapi/testPartitioning.cpp	2009-11-17 13:10:09 +0000
@@ -814,7 +814,20 @@ load_dist_table(Ndb* pNdb, int records, 
     CHECKNOTNULL(trans->insertTuple(distRecord, buf, 
                                     NULL, &opts, sizeof(opts)), trans);
 
-    CHECK(trans->execute(NdbTransaction::Commit), trans);
+    if (trans->execute(NdbTransaction::Commit) != 0)
+    {
+      NdbError err = trans->getNdbError();
+      if (err.status == NdbError::TemporaryError)
+      {
+        ndbout << err << endl;
+        NdbSleep_MilliSleep(50);
+        r--; // just retry
+      }
+      else
+      {
+        CHECK(-1, trans);
+      }
+    }
     trans->close();
   }
 

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2009-11-02 17:15:29 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2009-11-18 11:05:02 +0000
@@ -1472,3 +1472,19 @@ max-time: 300
 cmd: testNdbApi
 args: -n FragmentedApiFailure T1
 
+# Series of short (signal train) request generation/handling tests
+# Start
+max-time: 500
+cmd: testBasic
+args: --forceshortreqs -n PkUpdate
+
+max-time: 300
+cmd: testIndex
+args: --forceshortreqs -n InsertDelete T2
+
+max-time: 2500
+cmd: testPartitioning
+args: --forceshortreqs
+
+# End of short (signal train) handling tests
+

=== modified file 'storage/ndb/test/src/CMakeLists.txt'
--- a/storage/ndb/test/src/CMakeLists.txt	2009-10-07 06:35:51 +0000
+++ b/storage/ndb/test/src/CMakeLists.txt	2009-11-18 11:05:02 +0000
@@ -17,7 +17,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
                     ${CMAKE_SOURCE_DIR}/storage/ndb/src/common/mgmcommon
                     ${CMAKE_SOURCE_DIR}/storage/ndb/include/mgmcommon
                     ${CMAKE_SOURCE_DIR}/storage/ndb/include/kernel
-                    ${CMAKE_SOURCE_DIR}/storage/ndb/src/mgmapi)
+                    ${CMAKE_SOURCE_DIR}/storage/ndb/src/mgmapi
+                    ${CMAKE_SOURCE_DIR}/storage/ndb/include/debugger)
 INCLUDE(${CMAKE_SOURCE_DIR}/storage/ndb/config/type_ndbapitest.cmake)
 
 ADD_LIBRARY(ndbNDBT STATIC

=== modified file 'storage/ndb/test/src/Makefile.am'
--- a/storage/ndb/test/src/Makefile.am	2009-09-16 12:53:49 +0000
+++ b/storage/ndb/test/src/Makefile.am	2009-11-18 11:05:02 +0000
@@ -30,7 +30,7 @@ libNDBT_a_SOURCES = \
 	CpcClient.cpp NdbMixRestarter.cpp NDBT_Thread.cpp DbUtil.cpp \
 	SocketInputStream2.cpp NDBT_Find.cpp
 
-INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/common/mgmcommon -I$(top_srcdir)/storage/ndb/include/mgmcommon -I$(top_srcdir)/storage/ndb/include/kernel -I$(top_srcdir)/storage/ndb/src/mgmapi -I$(top_srcdir)/include
+INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/common/mgmcommon -I$(top_srcdir)/storage/ndb/include/mgmcommon -I$(top_srcdir)/storage/ndb/include/kernel -I$(top_srcdir)/storage/ndb/src/mgmapi -I$(top_srcdir)/include -I$(top_srcdir)/storage/ndb/include/debugger
 
 include $(top_srcdir)/storage/ndb/config/common.mk.am
 include $(top_srcdir)/storage/ndb/config/type_ndbapitest.mk.am

=== modified file 'storage/ndb/test/src/NDBT_Test.cpp'
--- a/storage/ndb/test/src/NDBT_Test.cpp	2009-11-11 18:04:01 +0000
+++ b/storage/ndb/test/src/NDBT_Test.cpp	2009-11-18 23:14:19 +0000
@@ -268,6 +268,7 @@ NDBT_Step::NDBT_Step(NDBT_TestCase* ptes
 {
 }
 
+#include <../../src/ndbapi/NdbImpl.hpp>
 
 int
 NDBT_Step::setUp(Ndb_cluster_connection& con){
@@ -282,6 +283,9 @@ NDBT_Step::setUp(Ndb_cluster_connection&
     m_ndb = new Ndb(&con, "TEST_DB" );
     m_ndb->init(1024);
 
+    NdbImpl::setForceShortRequests(m_ndb, 
+                                   m_ctx->suite->getForceShort());
+
     int result = m_ndb->waitUntilReady(300); // 5 minutes
     if (result != 0){
       g_err << "Ndb was not ready" << endl;
@@ -792,6 +796,7 @@ NDBT_TestSuite::NDBT_TestSuite(const cha
    temporaryTables = false;
    runonce = false;
    m_noddl = false;
+   m_forceShort = false;
 }
 
 
@@ -833,6 +838,10 @@ bool NDBT_TestSuite::getLogging() const 
   return m_logging;
 }
 
+bool NDBT_TestSuite::getForceShort() const {
+  return m_forceShort;
+}
+
 bool NDBT_TestSuite::timerIsOn(){
   return (timer != 0);
 }
@@ -927,6 +936,8 @@ NDBT_TestSuite::executeOneCtx(Ndb_cluste
     Ndb ndb(&con, "TEST_DB");
     ndb.init(1024);
 
+    NdbImpl::setForceShortRequests(&ndb, m_forceShort);
+
     int result = ndb.waitUntilReady(300); // 5 minutes
     if (result != 0){
       g_err << name <<": Ndb was not ready" << endl;
@@ -1276,6 +1287,7 @@ static int opt_seed = 0;
 static int opt_nologging = 0;
 static int opt_temporary = 0;
 static int opt_noddl = 0;
+static int opt_forceShort = 0;
 
 static struct my_option my_long_options[] =
 {
@@ -1316,6 +1328,9 @@ static struct my_option my_long_options[
   { "noddl", 0, "Don't create/drop tables as part of running tests",
     (uchar**) &opt_noddl, (uchar**) &opt_noddl, 0,
     GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+  { "forceshortreqs", 0, "Use short signals for NdbApi requests",
+    (uchar**) &opt_forceShort, (uchar**) &opt_forceShort, 0,
+    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
@@ -1386,6 +1401,7 @@ int NDBT_TestSuite::execute(int argc, co
     setLogging(false);
   temporaryTables = opt_temporary;
   m_noddl = opt_noddl;
+  m_forceShort = opt_forceShort;
 
   if (opt_seed == 0)
   {

=== modified file 'storage/ndb/tools/ndbinfo_sql.cpp'
--- a/storage/ndb/tools/ndbinfo_sql.cpp	2009-11-12 21:25:49 +0000
+++ b/storage/ndb/tools/ndbinfo_sql.cpp	2009-11-13 13:43:02 +0000
@@ -98,8 +98,8 @@ struct view {
     "  WHEN 5 THEN \"FILE_BUFFERS\""
     "  WHEN 6 THEN \"TRANSPORTER_BUFFERS\""
     "  ELSE \"<unknown>\" "
-    " END AS resource_id, "
-    "reserved, used, max, high "
+    " END AS resource_name, "
+    "reserved, used, max "
     "FROM <NDBINFO_DB>.<TABLE_PREFIX>resources"
    },
    { "counters",
@@ -142,15 +142,15 @@ struct view {
     "FROM <NDBINFO_DB>.<TABLE_PREFIX>nodes"
    },
   { "memoryusage",
-    "SELECT node_id, \"DATA_MEMORY\" "
-    "used, max, high "
+    "SELECT node_id, \"DATA_MEMORY\", "
+    "used, max "
     "FROM <NDBINFO_DB>.<TABLE_PREFIX>resources "
-    "WHERE resource_id = \"DATA_MEMORY|\" "
+    "WHERE resource_id = 3 "
     "UNION "
-    "SELECT node_id, \"INDEX_MEMORY\" "
-    "used, total, high "
+    "SELECT node_id, \"INDEX_MEMORY\", "
+    "used, total "
     "FROM <NDBINFO_DB>.<TABLE_PREFIX>pools "
-    "WHERE pool_name = \"Index memory|\" "
+    "WHERE block_number = 248 AND pool_name = \"Index memory\" "
   }
 };
 


Attachment: [text/bzr-bundle] bzr/msabaratnam@mysql.com-20091126163916-veqbqe1q95u0pmyh.bundle
Thread
bzr commit into mysql-5.1-telco-7.0-mai branch (msabaratnam:3207) Maitrayi Sabaratnam26 Nov