List:Commits« Previous MessageNext Message »
From:mikael Date:March 6 2007 6:36pm
Subject:bk commit into 5.1 tree (mikron:1.2438)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of mikron. When mikron does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-03-06 19:36:46+01:00, mikron@stripped +38 -0
  Merge 21.37.251.10.in-addr.arpa:/Users/mikron/mysql_clones/latest_wl3682
  into  21.37.251.10.in-addr.arpa:/Users/mikron/mysql_clones/bench_7
  MERGE: 1.2432.1.5

  config/ac-macros/ha_ndbcluster.m4@stripped, 2007-03-06 18:54:01+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.26.1.1

  configure.in@stripped, 2007-03-06 18:54:01+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.435.1.2

  sql/ha_ndbcluster.cc@stripped, 2007-03-06 19:36:44+01:00, mikron@stripped +6 -9
    Manual merge
    MERGE: 1.412.1.3

  sql/ha_ndbcluster.h@stripped, 2007-03-06 19:36:44+01:00, mikron@stripped +1 -1
    Manual merge
    MERGE: 1.165.1.7

  sql/ha_partition.cc@stripped, 2007-03-06 18:54:01+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.83.1.1

  sql/ha_partition.h@stripped, 2007-03-06 18:54:01+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.32.1.3

  sql/handler.h@stripped, 2007-03-06 18:54:02+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.252.1.4

  sql/mysqld.cc@stripped, 2007-03-06 18:54:02+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.620.1.1

  sql/sql_class.cc@stripped, 2007-03-06 18:54:02+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.312.1.1

  sql/sql_partition.cc@stripped, 2007-03-06 18:54:02+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.98.1.2

  storage/ndb/include/kernel/GlobalSignalNumbers.h@stripped, 2007-03-06 18:54:03+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.33.1.2

  storage/ndb/include/kernel/NodeInfo.hpp@stripped, 2007-03-06 18:54:03+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.9.1.1

  storage/ndb/include/kernel/signaldata/ApiRegSignalData.hpp@stripped, 2007-03-06 18:54:03+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.8.1.1

  storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp@stripped, 2007-03-06 18:54:03+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.15.1.3

  storage/ndb/include/mgmapi/ndb_logevent.h@stripped, 2007-03-06 19:36:44+01:00, mikron@stripped +0 -3
    Manual merge
    MERGE: 1.9.1.1

  storage/ndb/include/ndb_version.h.in@stripped, 2007-03-06 18:54:03+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.17.1.1

  storage/ndb/include/portlib/NdbTick.h@stripped, 2007-03-06 18:54:03+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.5.1.1

  storage/ndb/src/common/debugger/EventLogger.cpp@stripped, 2007-03-06 18:54:03+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.37.1.1

  storage/ndb/src/common/debugger/signaldata/SignalNames.cpp@stripped, 2007-03-06 18:54:03+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.18.1.2

  storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp@stripped, 2007-03-06 18:54:03+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.42.1.3

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2007-03-06 18:54:04+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.114.1.3

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp@stripped, 2007-03-06 18:54:04+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.47.1.2

  storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp@stripped, 2007-03-06 18:54:04+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.26.1.2

  storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp@stripped, 2007-03-06 18:54:04+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.100.1.4

  storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp@stripped, 2007-03-06 18:54:05+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.131.1.6

  storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp@stripped, 2007-03-06 18:54:05+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.48.1.1

  storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp@stripped, 2007-03-06 19:36:44+01:00, mikron@stripped +8 -6
    Manual merge
    MERGE: 1.136.1.2

  storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp@stripped, 2007-03-06 18:54:05+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.17.1.2

  storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp@stripped, 2007-03-06 18:54:05+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.14.1.1

  storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp@stripped, 2007-03-06 18:54:06+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.48.1.2

  storage/ndb/src/kernel/blocks/suma/Suma.cpp@stripped, 2007-03-06 18:54:06+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.52.1.2

  storage/ndb/src/kernel/blocks/suma/SumaInit.cpp@stripped, 2007-03-06 18:54:06+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.17.1.1

  storage/ndb/src/kernel/vm/GlobalData.hpp@stripped, 2007-03-06 18:54:06+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.10.1.1

  storage/ndb/src/kernel/vm/SimulatedBlock.hpp@stripped, 2007-03-06 18:54:06+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.30.1.1

  storage/ndb/src/mgmsrv/ConfigInfo.cpp@stripped, 2007-03-06 18:54:06+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.99.1.1

  storage/ndb/src/ndbapi/NdbScanOperation.cpp@stripped, 2007-03-06 18:54:06+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.106.1.2

  storage/ndb/test/ndbapi/testNodeRestart.cpp@stripped, 2007-03-06 18:54:06+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.40.1.2

  storage/ndb/test/run-test/daily-basic-tests.txt@stripped, 2007-03-06 18:54:07+01:00, mikron@stripped +0 -0
    Auto merged
    MERGE: 1.65.1.2

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	mikron
# Host:	21.37.251.10.in-addr.arpa
# Root:	/Users/mikron/mysql_clones/bench_7/RESYNC

--- 1.436/configure.in	2007-03-02 16:47:56 +01:00
+++ 1.437/configure.in	2007-03-06 18:54:01 +01:00
@@ -7,12 +7,12 @@
 AC_CANONICAL_SYSTEM
 # The Docs Makefile.am parses this line!
 # remember to also update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 5.1.16-ndb-6.2.0)
+AM_INIT_AUTOMAKE(mysql, 5.1.16-ndb-6.3.1)
 AM_CONFIG_HEADER(config.h)
 
 NDB_VERSION_MAJOR=6
-NDB_VERSION_MINOR=2
-NDB_VERSION_BUILD=0
+NDB_VERSION_MINOR=3
+NDB_VERSION_BUILD=1
 NDB_VERSION_STATUS="-beta"
 
 PROTOCOL_VERSION=10
@@ -1885,6 +1885,8 @@
   pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \
   pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \
   pthread_key_delete pthread_rwlock_rdlock pthread_setprio \
+  pthread_self sched_get_priority_min sched_get_priority_max \
+  sched_setaffinity processor_bind sched_setscheduler \
   pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \
   realpath rename rint rwlock_init setupterm \
   shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \
@@ -1906,6 +1908,47 @@
  *) AC_CHECK_FUNCS(clock_gettime)
     ;;
 esac
+#checking for Linux Scheduling Support
+AC_MSG_CHECKING(for Linux scheduling support)
+AC_TRY_LINK(
+  [#include <sys/types.h>
+   #include <linux/unistd.h>
+   #include <sched.h>
+   _syscall0(pid_t,gettid)],
+  [const struct sched_param *p= (const struct sched_param*)0;
+   pid_t tid = gettid();
+   int ret = sched_setaffinity(tid, 0, p);],
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(HAVE_LINUX_SCHEDULING, [1], [Linux scheduling function]),
+  AC_MSG_RESULT(no))
+
+#checking for Locking CPU support
+AC_MSG_CHECKING(for Linux affinity support)
+AC_TRY_LINK(
+  [#include <sys/types.h>
+   #include <linux/unistd.h>
+   #include <sched.h>
+   _syscall0(pid_t,gettid)],
+  [unsigned long *mask = (unsigned long *)0;
+   pid_t tid = gettid();
+   int ret = sched_setaffinity(tid, sizeof(unsigned long), mask);],
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(HAVE_LINUX_AFFINITY, [1], [Linux affinity function]),
+  AC_MSG_RESULT(no))
+
+AC_MSG_CHECKING(for Solaris affinity support)
+AC_TRY_LINK(
+  [#include <sys/types.h>
+   #include <sys/lwp.h>
+   #include <sys/processor.h>
+   #include <sys/procset.h>],
+  [processor_id_t *pid = (processor_id_t *)0;
+   processor_id_t cpu_id = (processor_id_t)0;
+   id_t tid = _lw_self();
+   int ret = processor_bind(P_LWPID, tid, cpu_id, bind);],
+  AC_MSG_RESULT(yes)
+  AC_DEFINE(HAVE_SOLARIS_AFFINITY, [1], [Solaris affinity function]),
+  AC_MSG_RESULT(no))
 
 # isinf() could be a function or a macro (HPUX)
 AC_MSG_CHECKING(for isinf with <math.h>)

--- 1.255/sql/handler.h	2007-02-19 18:21:52 +01:00
+++ 1.256/sql/handler.h	2007-03-06 18:54:02 +01:00
@@ -1259,6 +1259,8 @@
   virtual int info(uint)=0; // see my_base.h for full description
   virtual void get_dynamic_partition_info(PARTITION_INFO *stat_info,
                                           uint part_id);
+  virtual uint32 calculate_key_hash_value(Field **field_array)
+  { DBUG_ASSERT(0); }
   virtual int extra(enum ha_extra_function operation)
   { return 0; }
   virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
@@ -1449,7 +1451,9 @@
     *no_parts= 0;
     return 0;
   }
-  virtual void set_part_info(partition_info *part_info) {return;}
+  virtual void set_part_info(partition_info *part_info,
+                             bool early)
+  {return;}
 
   virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
 

--- 1.27/config/ac-macros/ha_ndbcluster.m4	2007-03-02 16:47:56 +01:00
+++ 1.28/config/ac-macros/ha_ndbcluster.m4	2007-03-06 18:54:01 +01:00
@@ -38,7 +38,7 @@
       if test -f "$mysql_sci_dir/lib/libsisci.a" -a \ 
               -f "$mysql_sci_dir/include/sisci_api.h"; then
         NDB_SCI_INCLUDES="-I$mysql_sci_dir/include"
-        NDB_SCI_LIBS="-L$mysql_sci_dir/lib -lsisci"
+        NDB_SCI_LIBS="$mysql_sci_dir/lib/libsisci.a"
         AC_MSG_RESULT([-- including sci transporter])
         AC_DEFINE([NDB_SCI_TRANSPORTER], [1],
                   [Including Ndb Cluster DB sci transporter])

--- 1.18/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp	2007-03-02 16:48:02 +01:00
+++ 1.19/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp	2007-03-06 18:54:03 +01:00
@@ -72,6 +72,11 @@
     NdbfsDumpAllFiles = 401,
     NdbfsDumpOpenFiles = 402,
     NdbfsDumpIdleFiles = 403,
+    CmvmiSchedulerExecutionTimer = 502,
+    CmvmiRealtimeScheduler = 503,
+    CmvmiExecuteLockCPU = 504,
+    CmvmiMaintLockCPU = 505,
+    CmvmiSchedulerSpinTimer = 506,
     // 1222-1225 DICT
     LqhDumpAllDefinedTabs = 1332,
     LqhDumpNoLogPages = 1333,

--- 1.6/storage/ndb/include/portlib/NdbTick.h	2007-02-20 15:37:13 +01:00
+++ 1.7/storage/ndb/include/portlib/NdbTick.h	2007-03-06 18:54:03 +01:00
@@ -38,7 +38,6 @@
 int NdbTick_CurrentMicrosecond(NDB_TICKS * secs, Uint32 * micros);
 
 #define TIME_MEASUREMENT
-#ifdef TIME_MEASUREMENT
 
 struct MicroSecondTimer {
   NDB_TICKS seconds;
@@ -54,7 +53,6 @@
 NDB_TICKS NdbTick_getMicrosPassed(struct MicroSecondTimer start,
                             struct MicroSecondTimer stop);
 int NdbTick_getMicroTimer(struct MicroSecondTimer* time_now);
-#endif
 
 #ifdef	__cplusplus
 }

--- 1.39/storage/ndb/src/common/debugger/EventLogger.cpp	2007-03-05 16:13:29 +01:00
+++ 1.40/storage/ndb/src/common/debugger/EventLogger.cpp	2007-03-06 18:54:03 +01:00
@@ -696,6 +696,12 @@
 		       "Mean loop Counter in doJob last 8192 times = %u",
 		       theData[1]);
 }
+void getTextThreadConfigLoop(QQQQ) {
+  BaseString::snprintf(m_text, m_text_len, 
+  "8192 loops,tot %u usec,exec %u extra:loops = %u,time %u,const %u",
+		       theData[1], theData[3], theData[4], theData[5],
+                       theData[2]);
+}
 void getTextSendBytesStatistic(QQQQ) {
   BaseString::snprintf(m_text, m_text_len, 
 		       "Mean send size to Node = %d last 4096 sends = %u bytes",
@@ -1036,6 +1042,7 @@
   ROW(OperationReportCounters, LogLevel::llStatistic,   8, Logger::LL_INFO ), 
   ROW(TableCreated,            LogLevel::llStatistic,   7, Logger::LL_INFO ),
   ROW(JobStatistic,            LogLevel::llStatistic,   9, Logger::LL_INFO ),
+  ROW(ThreadConfigLoop,        LogLevel::llStatistic,   9, Logger::LL_INFO ),
   ROW(SendBytesStatistic,      LogLevel::llStatistic,   9, Logger::LL_INFO ),
   ROW(ReceiveBytesStatistic,   LogLevel::llStatistic,   9, Logger::LL_INFO ),
   ROW(MemoryUsage,             LogLevel::llStatistic,   5, Logger::LL_INFO ),

--- 1.19/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp	2007-02-01 11:50:43 +01:00
+++ 1.20/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp	2007-03-06 18:54:03 +01:00
@@ -626,6 +626,14 @@
   ,{ GSN_LCP_PREPARE_REF,  "LCP_PREPARE_REF" }
   ,{ GSN_LCP_PREPARE_CONF, "LCP_PREPARE_CONF" }
 
+  ,{ GSN_DICT_ABORT_REQ,  "DICT_ABORT_REQ" }
+  ,{ GSN_DICT_ABORT_REF,  "DICT_ABORT_REF" }
+  ,{ GSN_DICT_ABORT_CONF, "DICT_ABORT_CONF" }
+
+  ,{ GSN_DICT_COMMIT_REQ,  "DICT_COMMIT_REQ" }
+  ,{ GSN_DICT_COMMIT_REF,  "DICT_COMMIT_REF" }
+  ,{ GSN_DICT_COMMIT_CONF, "DICT_COMMIT_CONF" }
+
   /* DICT LOCK */
   ,{ GSN_DICT_LOCK_REQ,          "DICT_LOCK_REQ" }
   ,{ GSN_DICT_LOCK_CONF,         "DICT_LOCK_CONF" }

--- 1.100/storage/ndb/src/mgmsrv/ConfigInfo.cpp	2007-03-02 16:48:27 +01:00
+++ 1.101/storage/ndb/src/mgmsrv/ConfigInfo.cpp	2007-03-06 18:54:06 +01:00
@@ -549,6 +549,42 @@
     STR_VALUE(MAX_INT_RNIL) },
 
   {
+    CFG_DB_EXECUTE_LOCK_CPU,
+    "LockExecuteThreadToCPU",
+    DB_TOKEN,
+    "CPU ID indicating which CPU will run the execution thread",
+    ConfigInfo::CI_USED,
+    true,
+    ConfigInfo::CI_INT,
+    "65535",
+    "0",
+    "65535" },
+
+  {
+    CFG_DB_MAINT_LOCK_CPU,
+    "LockMaintThreadsToCPU",
+    DB_TOKEN,
+    "CPU ID indicating which CPU will run the maintenance threads",
+    ConfigInfo::CI_USED,
+    true,
+    ConfigInfo::CI_INT,
+    "65535",
+    "0",
+    "65535" },
+
+  {
+    CFG_DB_REALTIME_SCHEDULER,
+    "RealtimeScheduler",
+    DB_TOKEN,
+    "If yes, then NDB Cluster threads will be scheduled as real-time threads",
+    ConfigInfo::CI_USED,
+    true,
+    ConfigInfo::CI_BOOL,
+    "false",
+    "false",
+    "true" },
+
+  {
     CFG_DB_MEMLOCK,
     "LockPagesInMainMemory",
     DB_TOKEN,
@@ -571,6 +607,30 @@
     "6000",
     "70",
     STR_VALUE(MAX_INT_RNIL) },
+
+  {
+    CFG_DB_SCHED_EXEC_TIME,
+    "SchedulerExecutionTimer",
+    DB_TOKEN,
+    "Number of microseconds to execute in scheduler before sending",
+    ConfigInfo::CI_USED,
+    false,
+    ConfigInfo::CI_INT,
+    "50",
+    "0",
+    "11000" },
+
+  {
+    CFG_DB_SCHED_SPIN_TIME,
+    "SchedulerSpinTimer",
+    DB_TOKEN,
+    "Number of microseconds to execute in scheduler before sleeping",
+    ConfigInfo::CI_USED,
+    false,
+    ConfigInfo::CI_INT,
+    "0",
+    "0",
+    "11000" },
 
   {
     CFG_DB_STOP_ON_ERROR,

--- 1.44/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2007-03-02 16:48:06 +01:00
+++ 1.45/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2007-03-06 18:54:03 +01:00
@@ -1186,7 +1186,31 @@
     }
     return;
   }
-  
+  if (arg == DumpStateOrd::CmvmiSchedulerExecutionTimer)
+  {
+    Uint32 exec_time = signal->theData[1];
+    globalEmulatorData.theConfiguration->schedulerExecutionTimer(exec_time);
+  }
+  if (arg == DumpStateOrd::CmvmiSchedulerSpinTimer)
+  {
+    Uint32 spin_time = signal->theData[1];
+    globalEmulatorData.theConfiguration->schedulerSpinTimer(spin_time);
+  } 
+  if (arg == DumpStateOrd::CmvmiRealtimeScheduler)
+  {
+    bool realtime_on = signal->theData[1];
+    globalEmulatorData.theConfiguration->realtimeScheduler(realtime_on);
+  }
+  if (arg == DumpStateOrd::CmvmiExecuteLockCPU)
+  {
+    Uint32 exec_cpu_id = signal->theData[1];
+    globalEmulatorData.theConfiguration->executeLockCPU(exec_cpu_id);
+  }
+  if (arg == DumpStateOrd::CmvmiMaintLockCPU)
+  {
+    Uint32 maint_cpu_id = signal->theData[1];
+    globalEmulatorData.theConfiguration->maintLockCPU(maint_cpu_id);
+  }
   if (arg == DumpStateOrd::CmvmiSetRestartOnErrorInsert)
   {
     if(signal->getLength() == 1)

--- 1.116/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2007-03-02 16:48:09 +01:00
+++ 1.117/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2007-03-06 18:54:04 +01:00
@@ -14020,7 +14020,8 @@
 
 //******************************************
 void
-Dbdict::execCREATE_FILE_REQ(Signal* signal){
+Dbdict::execCREATE_FILE_REQ(Signal* signal)
+{
   jamEntry();
   
   if(!assembleFragments(signal)){
@@ -14056,13 +14057,14 @@
 
     Ptr<SchemaTransaction> trans_ptr;
     if (! c_Trans.seize(trans_ptr)){
+      jam();
       ref->errorCode = CreateFileRef::Busy;
       ref->status    = 0;
       ref->errorKey  = 0;
       ref->errorLine = __LINE__;
       break;
     }
-    
+    jam(); 
     const Uint32 trans_key = ++c_opRecordSequence;
     trans_ptr.p->key = trans_key;
     trans_ptr.p->m_senderRef = senderRef;
@@ -14091,6 +14093,7 @@
     {
       Uint32 objId = getFreeObjId(0);
       if (objId == RNIL) {
+        jam();
         ref->errorCode = CreateFileRef::NoMoreObjectRecords;
         ref->status    = 0;
         ref->errorKey  = 0;
@@ -14115,7 +14118,6 @@
 	       CreateObjReq::SignalLength, JBB);
 
     c_blockState = BS_CREATE_TAB;
-
     return;
   } while(0);
   
@@ -14126,7 +14128,8 @@
 }
 
 void
-Dbdict::execCREATE_FILEGROUP_REQ(Signal* signal){
+Dbdict::execCREATE_FILEGROUP_REQ(Signal* signal)
+{
   jamEntry();
   
   if(!assembleFragments(signal)){
@@ -14161,13 +14164,14 @@
 
     Ptr<SchemaTransaction> trans_ptr;
     if (! c_Trans.seize(trans_ptr)){
+      jam();
       ref->errorCode = CreateFilegroupRef::Busy;
       ref->status    = 0;
       ref->errorKey  = 0;
       ref->errorLine = __LINE__;
       break;
     }
-    
+    jam(); 
     const Uint32 trans_key = ++c_opRecordSequence;
     trans_ptr.p->key = trans_key;
     trans_ptr.p->m_senderRef = senderRef;
@@ -14193,6 +14197,7 @@
     {
       Uint32 objId = getFreeObjId(0);
       if (objId == RNIL) {
+        jam();
         ref->errorCode = CreateFilegroupRef::NoMoreObjectRecords;
         ref->status    = 0;
         ref->errorKey  = 0;
@@ -14217,7 +14222,6 @@
 	       CreateObjReq::SignalLength, JBB);
 
     c_blockState = BS_CREATE_TAB;
-
     return;
   } while(0);
   
@@ -14264,6 +14268,7 @@
     Ptr<File> file_ptr;
     if (!c_file_hash.find(file_ptr, objId))
     {
+      jam();
       ref->errorCode = DropFileRef::NoSuchFile;
       ref->errorLine = __LINE__;
       break;
@@ -14271,6 +14276,7 @@
     
     if (file_ptr.p->m_version != version)
     {
+      jam();
       ref->errorCode = DropFileRef::InvalidSchemaObjectVersion;
       ref->errorLine = __LINE__;
       break;
@@ -14279,11 +14285,12 @@
     Ptr<SchemaTransaction> trans_ptr;
     if (! c_Trans.seize(trans_ptr))
     {
+      jam();
       ref->errorCode = CreateFileRef::Busy;
       ref->errorLine = __LINE__;
       break;
     }
-    
+    jam();
     const Uint32 trans_key = ++c_opRecordSequence;
     trans_ptr.p->key = trans_key;
     trans_ptr.p->m_senderRef = senderRef;
@@ -14318,7 +14325,6 @@
 	       DropObjReq::SignalLength, JBB);
 
     c_blockState = BS_CREATE_TAB;
-
     return;
   } while(0);
   
@@ -14365,6 +14371,7 @@
     Ptr<Filegroup> filegroup_ptr;
     if (!c_filegroup_hash.find(filegroup_ptr, objId))
     {
+      jam();
       ref->errorCode = DropFilegroupRef::NoSuchFilegroup;
       ref->errorLine = __LINE__;
       break;
@@ -14372,6 +14379,7 @@
 
     if (filegroup_ptr.p->m_version != version)
     {
+      jam();
       ref->errorCode = DropFilegroupRef::InvalidSchemaObjectVersion;
       ref->errorLine = __LINE__;
       break;
@@ -14380,11 +14388,13 @@
     Ptr<SchemaTransaction> trans_ptr;
     if (! c_Trans.seize(trans_ptr))
     {
+      jam();
       ref->errorCode = CreateFilegroupRef::Busy;
       ref->errorLine = __LINE__;
       break;
     }
-    
+   
+    jam();
     const Uint32 trans_key = ++c_opRecordSequence;
     trans_ptr.p->key = trans_key;
     trans_ptr.p->m_senderRef = senderRef;
@@ -14419,7 +14429,6 @@
 	       DropObjReq::SignalLength, JBB);
 
     c_blockState = BS_CREATE_TAB;
-
     return;
   } while(0);
   
@@ -14430,15 +14439,15 @@
 }
 
 void
-Dbdict::execCREATE_OBJ_REF(Signal* signal){
-  jamEntry();
-
+Dbdict::execCREATE_OBJ_REF(Signal* signal)
+{
   CreateObjRef * const ref = (CreateObjRef*)signal->getDataPtr();
-  
   Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
   ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
-  
   if(ref->errorCode != CreateObjRef::NF_FakeErrorREF){
+    jam();
     trans_ptr.p->setErrorCode(ref->errorCode);
   }
   Uint32 node = refToNode(ref->senderRef);
@@ -14446,12 +14455,12 @@
 }
 
 void
-Dbdict::execCREATE_OBJ_CONF(Signal* signal){
-  jamEntry();
-
-  CreateObjConf * const conf = (CreateObjConf*)signal->getDataPtr();
-  
+Dbdict::execCREATE_OBJ_CONF(Signal* signal)
+{
   Ptr<SchemaTransaction> trans_ptr;
+  CreateObjConf * const conf = (CreateObjConf*)signal->getDataPtr();
+
+  jamEntry();
   ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
   schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
 }
@@ -14461,6 +14470,7 @@
 		       SchemaTransaction * trans_ptr_p, 
 		       Uint32 nodeId)
 {
+  jam();
   {
     SafeCounter tmp(c_counterMgr, trans_ptr_p->m_counter);
     if(!tmp.clearWaitingFor(nodeId)){
@@ -14471,10 +14481,8 @@
   
   switch(trans_ptr_p->m_op.m_state){
   case DictObjOp::Preparing:{
-    
     if(trans_ptr_p->m_errorCode != 0)
     {
-      jam();
       /**
        * Failed to prepare on atleast one node -> abort on all
        */
@@ -14484,10 +14492,16 @@
 	safe_cast(&Dbdict::trans_abort_start_done);
       
       if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_start)
+      {
+        jam();
 	(this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_start)
 	  (signal, trans_ptr_p);
+      }
       else
+      {
+        jam();
 	execute(signal, trans_ptr_p->m_callback, 0);
+      }
       return;
     }
     
@@ -14497,14 +14511,19 @@
       safe_cast(&Dbdict::trans_commit_start_done);
     
     if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_start)
+    {
+      jam();
       (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_start)
 	(signal, trans_ptr_p);
+    }
     else
+    {
+      jam();
       execute(signal, trans_ptr_p->m_callback, 0);
+    }
     return;
   }
   case DictObjOp::Committing: {
-    jam();
     ndbrequire(trans_ptr_p->m_errorCode == 0);
 
     trans_ptr_p->m_op.m_state = DictObjOp::Committed;
@@ -14513,31 +14532,42 @@
       safe_cast(&Dbdict::trans_commit_complete_done);
     
     if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_complete)
+    {
+      jam();
       (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_commit_complete)
 	(signal, trans_ptr_p);
+    }
     else
-      execute(signal, trans_ptr_p->m_callback, 0);      
+    {
+      jam();
+      execute(signal, trans_ptr_p->m_callback, 0);
+    }
     return;
   }
   case DictObjOp::Aborting:{
-    jam();
-
     trans_ptr_p->m_op.m_state = DictObjOp::Committed;
     trans_ptr_p->m_callback.m_callbackData = trans_ptr_p->key;
     trans_ptr_p->m_callback.m_callbackFunction= 
       safe_cast(&Dbdict::trans_abort_complete_done);
 
     if(f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_complete)
+    {
+      jam();
       (this->*f_dict_op[trans_ptr_p->m_op.m_vt_index].m_trans_abort_complete)
 	(signal, trans_ptr_p);
+    }
     else
-      execute(signal, trans_ptr_p->m_callback, 0);      
+    {
+      jam();
+      execute(signal, trans_ptr_p->m_callback, 0);
+    }
     return;
   }
   case DictObjOp::Defined:
   case DictObjOp::Prepared:
   case DictObjOp::Committed:
   case DictObjOp::Aborted:
+    jam();
     break;
   }
   ndbrequire(false);
@@ -14546,14 +14576,13 @@
 void
 Dbdict::trans_commit_start_done(Signal* signal, 
 				Uint32 callbackData,
-				Uint32 retValue){
-  jamEntry();
-  
-  ndbrequire(retValue == 0);
-  
+				Uint32 retValue)
+{
   Ptr<SchemaTransaction> trans_ptr;
+
+  jam();
+  ndbrequire(retValue == 0);
   ndbrequire(c_Trans.find(trans_ptr, callbackData));
-  
   NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
   SafeCounter tmp(c_counterMgr, trans_ptr.p->m_counter);
   tmp.init<DictCommitRef>(rg, GSN_DICT_COMMIT_REF, trans_ptr.p->key);
@@ -14564,27 +14593,26 @@
   req->op_key = trans_ptr.p->m_op.m_key;
   sendSignal(rg, GSN_DICT_COMMIT_REQ, signal, DictCommitReq::SignalLength, 
 	     JBB);
-  
   trans_ptr.p->m_op.m_state = DictObjOp::Committing;
 }
 
 void
 Dbdict::trans_commit_complete_done(Signal* signal, 
 				   Uint32 callbackData,
-				   Uint32 retValue){
-  jamEntry();
-  
-  ndbrequire(retValue == 0);
-  
+				   Uint32 retValue)
+{
   Ptr<SchemaTransaction> trans_ptr;
+
+  jam();
+  ndbrequire(retValue == 0);
   ndbrequire(c_Trans.find(trans_ptr, callbackData));
 
   switch(f_dict_op[trans_ptr.p->m_op.m_vt_index].m_gsn_user_req){
   case GSN_CREATE_FILEGROUP_REQ:{
     FilegroupPtr fg_ptr;
+    jam();
     ndbrequire(c_filegroup_hash.find(fg_ptr, trans_ptr.p->m_op.m_obj_id));
     
-    //
     CreateFilegroupConf * conf = (CreateFilegroupConf*)signal->getDataPtr();
     conf->senderRef = reference();
     conf->senderData = trans_ptr.p->m_senderData;
@@ -14594,11 +14622,11 @@
     //@todo check api failed
     sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILEGROUP_CONF, signal, 
 	       CreateFilegroupConf::SignalLength, JBB);
-
     break;
   }
   case GSN_CREATE_FILE_REQ:{
     FilePtr f_ptr;
+    jam();
     ndbrequire(c_file_hash.find(f_ptr, trans_ptr.p->m_op.m_obj_id));
     CreateFileConf * conf = (CreateFileConf*)signal->getDataPtr();
     conf->senderRef = reference();
@@ -14609,11 +14637,11 @@
     //@todo check api failed
     sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILE_CONF, signal, 
 	       CreateFileConf::SignalLength, JBB);
-    
     break;
   }
   case GSN_DROP_FILE_REQ:{
     DropFileConf * conf = (DropFileConf*)signal->getDataPtr();
+    jam();
     conf->senderRef = reference();
     conf->senderData = trans_ptr.p->m_senderData;
     conf->fileId = trans_ptr.p->m_op.m_obj_id;
@@ -14625,6 +14653,7 @@
   }
   case GSN_DROP_FILEGROUP_REQ:{
     DropFilegroupConf * conf = (DropFilegroupConf*)signal->getDataPtr();
+    jam();
     conf->senderRef = reference();
     conf->senderData = trans_ptr.p->m_senderData;
     conf->filegroupId = trans_ptr.p->m_op.m_obj_id;
@@ -14647,12 +14676,12 @@
 void
 Dbdict::trans_abort_start_done(Signal* signal, 
 			       Uint32 callbackData,
-			       Uint32 retValue){
-  jamEntry();
-  
-  ndbrequire(retValue == 0);
-
+			       Uint32 retValue)
+{
   Ptr<SchemaTransaction> trans_ptr;
+
+  jam();
+  ndbrequire(retValue == 0);
   ndbrequire(c_Trans.find(trans_ptr, callbackData));
   
   NodeReceiverGroup rg(DBDICT, trans_ptr.p->m_nodes);
@@ -14670,12 +14699,12 @@
 void
 Dbdict::trans_abort_complete_done(Signal* signal, 
 				  Uint32 callbackData,
-				  Uint32 retValue){
-  jamEntry();
-  
-  ndbrequire(retValue == 0);
-  
+				  Uint32 retValue)
+{
   Ptr<SchemaTransaction> trans_ptr;
+
+  jam();
+  ndbrequire(retValue == 0);
   ndbrequire(c_Trans.find(trans_ptr, callbackData));
 
   switch(f_dict_op[trans_ptr.p->m_op.m_vt_index].m_gsn_user_req){
@@ -14683,6 +14712,7 @@
   {
     //
     CreateFilegroupRef * ref = (CreateFilegroupRef*)signal->getDataPtr();
+    jam();
     ref->senderRef = reference();
     ref->senderData = trans_ptr.p->m_senderData;
     ref->masterNodeId = c_masterNodeId;
@@ -14694,12 +14724,12 @@
     //@todo check api failed
     sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILEGROUP_REF, signal, 
 	       CreateFilegroupRef::SignalLength, JBB);
-
     break;
   }
   case GSN_CREATE_FILE_REQ:
   {
     CreateFileRef * ref = (CreateFileRef*)signal->getDataPtr();
+    jam();
     ref->senderRef = reference();
     ref->senderData = trans_ptr.p->m_senderData;
     ref->masterNodeId = c_masterNodeId;
@@ -14711,12 +14741,12 @@
     //@todo check api failed
     sendSignal(trans_ptr.p->m_senderRef, GSN_CREATE_FILE_REF, signal, 
 	       CreateFileRef::SignalLength, JBB);
-    
     break;
   }
   case GSN_DROP_FILE_REQ:
   {
     DropFileRef * ref = (DropFileRef*)signal->getDataPtr();
+    jam();
     ref->senderRef = reference();
     ref->senderData = trans_ptr.p->m_senderData;
     ref->masterNodeId = c_masterNodeId;
@@ -14727,13 +14757,13 @@
     //@todo check api failed
     sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILE_REF, signal, 
 	       DropFileRef::SignalLength, JBB);
-    
     break;
   }
   case GSN_DROP_FILEGROUP_REQ:
   {
     //
     DropFilegroupRef * ref = (DropFilegroupRef*)signal->getDataPtr();
+    jam();
     ref->senderRef = reference();
     ref->senderData = trans_ptr.p->m_senderData;
     ref->masterNodeId = c_masterNodeId;
@@ -14744,7 +14774,6 @@
     //@todo check api failed
     sendSignal(trans_ptr.p->m_senderRef, GSN_DROP_FILEGROUP_REF, signal, 
 	       DropFilegroupRef::SignalLength, JBB);
-
     break;
   }
   default:
@@ -14758,7 +14787,8 @@
 }
 
 void
-Dbdict::execCREATE_OBJ_REQ(Signal* signal){
+Dbdict::execCREATE_OBJ_REQ(Signal* signal)
+{
   jamEntry();
 
   if(!assembleFragments(signal)){
@@ -14803,6 +14833,7 @@
   switch(objType){
   case DictTabInfo::Tablespace:
   case DictTabInfo::LogfileGroup:
+    jam();
     createObjPtr.p->m_vt_index = 0;
     break;
   case DictTabInfo::Datafile:
@@ -14811,7 +14842,11 @@
      * Use restart code to impl. ForceCreateFile
      */
     if (requestInfo & CreateFileReq::ForceCreateFile)
-      createObjPtr.p->m_restart= 2;      
+    {
+      jam();
+      createObjPtr.p->m_restart= 2;
+    }
+    jam();
     createObjPtr.p->m_vt_index = 1;
     break;
   default:
@@ -14827,10 +14862,10 @@
 Dbdict::execDICT_COMMIT_REQ(Signal* signal)
 {
   DictCommitReq* req = (DictCommitReq*)signal->getDataPtr();
-
   Ptr<SchemaOp> op;
-  ndbrequire(c_schemaOp.find(op, req->op_key));
 
+  jamEntry();
+  ndbrequire(c_schemaOp.find(op, req->op_key));
   (this->*f_dict_op[op.p->m_vt_index].m_commit)(signal, op.p);
 }
 
@@ -14838,23 +14873,23 @@
 Dbdict::execDICT_ABORT_REQ(Signal* signal)
 {
   DictAbortReq* req = (DictAbortReq*)signal->getDataPtr();
-
   Ptr<SchemaOp> op;
-  ndbrequire(c_schemaOp.find(op, req->op_key));
 
+  jamEntry();
+  ndbrequire(c_schemaOp.find(op, req->op_key));
   (this->*f_dict_op[op.p->m_vt_index].m_abort)(signal, op.p);
 }
 
 void
-Dbdict::execDICT_COMMIT_REF(Signal* signal){
-  jamEntry();
-  
+Dbdict::execDICT_COMMIT_REF(Signal* signal)
+{
   DictCommitRef * const ref = (DictCommitRef*)signal->getDataPtr();
-  
   Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
   ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
-  
   if(ref->errorCode != DictCommitRef::NF_FakeErrorREF){
+    jam();
     trans_ptr.p->setErrorCode(ref->errorCode);
   }
   Uint32 node = refToNode(ref->senderRef);
@@ -14862,26 +14897,26 @@
 }
 
 void
-Dbdict::execDICT_COMMIT_CONF(Signal* signal){
-  jamEntry();
-  
-  DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
-  
+Dbdict::execDICT_COMMIT_CONF(Signal* signal)
+{
   Ptr<SchemaTransaction> trans_ptr;
+  DictCommitConf * const conf = (DictCommitConf*)signal->getDataPtr();
+
+  jamEntry();
   ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
   schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
 }
 
 void
-Dbdict::execDICT_ABORT_REF(Signal* signal){
-  jamEntry();
-  
+Dbdict::execDICT_ABORT_REF(Signal* signal)
+{
   DictAbortRef * const ref = (DictAbortRef*)signal->getDataPtr();
-  
   Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
   ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
-  
   if(ref->errorCode != DictAbortRef::NF_FakeErrorREF){
+    jam();
     trans_ptr.p->setErrorCode(ref->errorCode);
   }
   Uint32 node = refToNode(ref->senderRef);
@@ -14889,31 +14924,28 @@
 }
 
 void
-Dbdict::execDICT_ABORT_CONF(Signal* signal){
-  jamEntry();
-  
+Dbdict::execDICT_ABORT_CONF(Signal* signal)
+{
   DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
-  
   Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
   ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
   schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
 }
 
-
-
 void
 Dbdict::createObj_prepare_start_done(Signal* signal,
 				     Uint32 callbackData, 
-				     Uint32 returnCode){
+				     Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;  
+  SegmentedSectionPtr objInfoPtr;
   
   ndbrequire(returnCode == 0);
-
-  CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-
-  SegmentedSectionPtr objInfoPtr;
+  jam();
   getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
-  
   if(createObjPtr.p->m_errorCode != 0){
     jam();
     createObjPtr.p->m_obj_info_ptr_i= RNIL;
@@ -14941,19 +14973,19 @@
 void
 Dbdict::createObj_writeSchemaConf1(Signal* signal, 
 				   Uint32 callbackData,
-				   Uint32 returnCode){
-  jam();
+				   Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;  
+  Callback callback;
+  SegmentedSectionPtr objInfoPtr;
 
+  jam();
   ndbrequire(returnCode == 0);
-
-  CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
   
-  Callback callback;
   callback.m_callbackData = createObjPtr.p->key;
   callback.m_callbackFunction = safe_cast(&Dbdict::createObj_writeObjConf);
   
-  SegmentedSectionPtr objInfoPtr;
   getSection(objInfoPtr, createObjPtr.p->m_obj_info_ptr_i);
   writeTableFile(signal, createObjPtr.p->m_obj_id, objInfoPtr, &callback);
   
@@ -14965,14 +14997,13 @@
 void
 Dbdict::createObj_writeObjConf(Signal* signal, 
 			       Uint32 callbackData,
-			       Uint32 returnCode){
-  jam();
+			       Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
 
+  jam();
   ndbrequire(returnCode == 0);
-  
-  CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-
   createObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::createObj_prepare_complete_done);
   (this->*f_dict_op[createObjPtr.p->m_vt_index].m_prepare_complete)
@@ -14982,12 +15013,12 @@
 void
 Dbdict::createObj_prepare_complete_done(Signal* signal, 
 					Uint32 callbackData,
-					Uint32 returnCode){
+					Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
+
   jam();
-  
   ndbrequire(returnCode == 0);
-  
-  CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
   
   //@todo check for master failed
@@ -15016,28 +15047,33 @@
 }
 
 void
-Dbdict::createObj_commit(Signal * signal, SchemaOp * op){
-  jam();
-  
+Dbdict::createObj_commit(Signal * signal, SchemaOp * op)
+{
   OpCreateObj * createObj = (OpCreateObj*)op;
+
   createObj->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::createObj_commit_start_done);
   if (f_dict_op[createObj->m_vt_index].m_commit_start)
+  {
+    jam();
     (this->*f_dict_op[createObj->m_vt_index].m_commit_start)(signal, createObj);
+  }
   else
+  {
+    jam();
     execute(signal, createObj->m_callback, 0);
+  }
 }
 
 void
 Dbdict::createObj_commit_start_done(Signal* signal, 
 				    Uint32 callbackData,
-				    Uint32 returnCode){
+				    Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;  
   
   jam();
-  
   ndbrequire(returnCode == 0);
-  
-  CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
   
   Uint32 objId = createObjPtr.p->m_obj_id;
@@ -15057,29 +15093,35 @@
 void
 Dbdict::createObj_writeSchemaConf2(Signal* signal, 
 				   Uint32 callbackData,
-				   Uint32 returnCode){
-  jam();
-  
-  CreateObjRecordPtr createObjPtr;  
-  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
+				   Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
 
+  ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
   createObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::createObj_commit_complete_done);
   if (f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
+  {
+    jam();
     (this->*f_dict_op[createObjPtr.p->m_vt_index].m_commit_complete)
       (signal, createObjPtr.p);
+  }
   else
+  {
+    jam();
     execute(signal, createObjPtr.p->m_callback, 0);
+  }
   
 }
 
 void
 Dbdict::createObj_commit_complete_done(Signal* signal, 
 				       Uint32 callbackData,
-				       Uint32 returnCode){
+				       Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
+
   jam();
-  
-  CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
   
   //@todo check error
@@ -15097,27 +15139,31 @@
 void
 Dbdict::createObj_abort(Signal* signal, SchemaOp* op)
 {
-  jam();
-  
   OpCreateObj * createObj = (OpCreateObj*)op;
   
   createObj->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::createObj_abort_start_done);
   if (f_dict_op[createObj->m_vt_index].m_abort_start)
+  {
+    jam();
     (this->*f_dict_op[createObj->m_vt_index].m_abort_start)(signal, createObj);
+  }
   else
+  {
+    jam();
     execute(signal, createObj->m_callback, 0);
+  }
 }
 
 void
 Dbdict::createObj_abort_start_done(Signal* signal, 
 				   Uint32 callbackData,
-				   Uint32 returnCode){
+				   Uint32 returnCode)
+{
+  CreateObjRecordPtr createObjPtr;
+
   jam();
-  
-  CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-  
   XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
   SchemaFile::TableEntry objEntry = * getTableEntry(xsf, 
 						    createObjPtr.p->m_obj_id);
@@ -15136,19 +15182,23 @@
 					Uint32 callbackData,
 					Uint32 returnCode)
 {
-  jam();
+  CreateObjRecordPtr createObjPtr;
 
-  CreateObjRecordPtr createObjPtr;  
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
-
   createObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::createObj_abort_complete_done);
   
   if (f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
+  {
+    jam();
     (this->*f_dict_op[createObjPtr.p->m_vt_index].m_abort_complete)
       (signal, createObjPtr.p);
+  }
   else
+  {
+    jam();
     execute(signal, createObjPtr.p->m_callback, 0);
+  }
 }
 
 void
@@ -15156,9 +15206,9 @@
 				      Uint32 callbackData,
 				      Uint32 returnCode)
 {
-  jam();
+  CreateObjRecordPtr createObjPtr;
 
-  CreateObjRecordPtr createObjPtr;  
+  jam();
   ndbrequire(c_opCreateObj.find(createObjPtr, callbackData));
 
   DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
@@ -15171,7 +15221,8 @@
 }
 
 void
-Dbdict::execDROP_OBJ_REQ(Signal* signal){
+Dbdict::execDROP_OBJ_REQ(Signal* signal)
+{
   jamEntry();
 
   if(!assembleFragments(signal)){
@@ -15210,8 +15261,9 @@
   case DictTabInfo::Tablespace:
   case DictTabInfo::LogfileGroup:
   {
-    dropObjPtr.p->m_vt_index = 3;
     Ptr<Filegroup> fg_ptr;
+    jam();
+    dropObjPtr.p->m_vt_index = 3;
     ndbrequire(c_filegroup_hash.find(fg_ptr, objId));
     dropObjPtr.p->m_obj_ptr_i = fg_ptr.i;
     break;
@@ -15219,15 +15271,19 @@
   }
   case DictTabInfo::Datafile:
   {
-    dropObjPtr.p->m_vt_index = 2;
     Ptr<File> file_ptr;
+    jam();
+    dropObjPtr.p->m_vt_index = 2;
     ndbrequire(c_file_hash.find(file_ptr, objId));
     dropObjPtr.p->m_obj_ptr_i = file_ptr.i;
     break;
   }
   case DictTabInfo::Undofile:
+  {
+    jam();
     dropObjPtr.p->m_vt_index = 4;
     return;
+  }
   default:
     ndbrequire(false);
   }
@@ -15242,12 +15298,12 @@
 				   Uint32 callbackData,
 				   Uint32 returnCode)
 {
-  ndbrequire(returnCode == 0);
+  DropObjRecordPtr dropObjPtr;
+  Callback cb;
 
-  DropObjRecordPtr dropObjPtr;  
+  ndbrequire(returnCode == 0);
   ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
 
-  Callback cb;
   cb.m_callbackData = callbackData;
   cb.m_callbackFunction = 
     safe_cast(&Dbdict::dropObj_prepare_writeSchemaConf);
@@ -15258,7 +15314,7 @@
     dropObj_prepare_complete_done(signal, callbackData, 0);
     return;
   }
-  
+  jam();  
   Uint32 objId = dropObjPtr.p->m_obj_id;
   XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
   SchemaFile::TableEntry objEntry = *getTableEntry(xsf, objId);
@@ -15271,19 +15327,23 @@
 					Uint32 callbackData,
 					Uint32 returnCode)
 {
-  ndbrequire(returnCode == 0);
+  DropObjRecordPtr dropObjPtr;
 
-  DropObjRecordPtr dropObjPtr;  
+  ndbrequire(returnCode == 0);
   ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-  
   dropObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::dropObj_prepare_complete_done);
-  
   if(f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
+  {
+    jam();
     (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_prepare_complete)
       (signal, dropObjPtr.p);
+  }
   else
+  {
+    jam();
     execute(signal, dropObjPtr.p->m_callback, 0);
+  }
 }
 
 void
@@ -15291,10 +15351,11 @@
 				      Uint32 callbackData,
 				      Uint32 returnCode)
 {
+  DropObjRecordPtr dropObjPtr;
+
   ndbrequire(returnCode == 0);
-  
-  DropObjRecordPtr dropObjPtr;  
   ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  jam();
   
   //@todo check for master failed
   
@@ -15320,16 +15381,22 @@
 }
 
 void
-Dbdict::dropObj_commit(Signal * signal, SchemaOp * op){
-  jam();
-  
+Dbdict::dropObj_commit(Signal * signal, SchemaOp * op)
+{
   OpDropObj * dropObj = (OpDropObj*)op;
+
   dropObj->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::dropObj_commit_start_done);
   if (f_dict_op[dropObj->m_vt_index].m_commit_start)
+  {
+    jam();
     (this->*f_dict_op[dropObj->m_vt_index].m_commit_start)(signal, dropObj);
+  }
   else
+  {
+    jam();
     execute(signal, dropObj->m_callback, 0);
+  }
 }
 
 void
@@ -15337,10 +15404,10 @@
 				  Uint32 callbackData,
 				  Uint32 returnCode)
 {
+  DropObjRecordPtr dropObjPtr;
+
   jam();
   ndbrequire(returnCode == 0);
-
-  DropObjRecordPtr dropObjPtr;  
   ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
   
   Uint32 objId = dropObjPtr.p->m_obj_id;
@@ -15361,20 +15428,25 @@
 				       Uint32 callbackData,
 				       Uint32 returnCode)
 {
+  DropObjRecordPtr dropObjPtr;
+
   jam();
   ndbrequire(returnCode == 0);
-  
-  DropObjRecordPtr dropObjPtr;  
   ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-  
   dropObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::dropObj_commit_complete_done);
   
   if(f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
+  {
+    jam();
     (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_commit_complete)
       (signal, dropObjPtr.p);
+  }
   else
+  {
+    jam();
     execute(signal, dropObjPtr.p->m_callback, 0);
+  }
 }
 
 void
@@ -15382,7 +15454,9 @@
 				     Uint32 callbackData,
 				     Uint32 returnCode)
 {
-  DropObjRecordPtr dropObjPtr;  
+  DropObjRecordPtr dropObjPtr;
+
+  jam();
   ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
   
   //@todo check error
@@ -15393,22 +15467,26 @@
   conf->senderData = dropObjPtr.p->m_senderData;
   sendSignal(dropObjPtr.p->m_senderRef, GSN_DICT_COMMIT_CONF,
 	     signal, DictCommitConf::SignalLength, JBB);
-  
   c_opDropObj.release(dropObjPtr);
 }
 
 void
-Dbdict::dropObj_abort(Signal * signal, SchemaOp * op){
-  jam();
-  
+Dbdict::dropObj_abort(Signal * signal, SchemaOp * op)
+{
   OpDropObj * dropObj = (OpDropObj*)op;
+
   dropObj->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::dropObj_abort_start_done);
-
   if (f_dict_op[dropObj->m_vt_index].m_abort_start)
+  {
+    jam();
     (this->*f_dict_op[dropObj->m_vt_index].m_abort_start)(signal, dropObj);
+  }
   else
+  {
+    jam();
     execute(signal, dropObj->m_callback, 0);
+  }
 }
 
 void
@@ -15416,10 +15494,10 @@
 				 Uint32 callbackData,
 				 Uint32 returnCode)
 {
+  DropObjRecordPtr dropObjPtr;
+
   jam();
   ndbrequire(returnCode == 0);
-
-  DropObjRecordPtr dropObjPtr;  
   ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
   
   XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
@@ -15440,6 +15518,7 @@
   }
   else
   {
+    jam();
     execute(signal, callback, 0);
   }
 }
@@ -15449,20 +15528,24 @@
 				      Uint32 callbackData,
 				      Uint32 returnCode)
 {
-  jam();
+  DropObjRecordPtr dropObjPtr;
+
   ndbrequire(returnCode == 0);
-  
-  DropObjRecordPtr dropObjPtr;  
   ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-  
   dropObjPtr.p->m_callback.m_callbackFunction = 
     safe_cast(&Dbdict::dropObj_abort_complete_done);
   
   if(f_dict_op[dropObjPtr.p->m_vt_index].m_abort_complete)
+  {
+    jam();
     (this->*f_dict_op[dropObjPtr.p->m_vt_index].m_abort_complete)
       (signal, dropObjPtr.p);
+  }
   else
+  {
+    jam();
     execute(signal, dropObjPtr.p->m_callback, 0);
+  }
 }
 
 void
@@ -15470,24 +15553,26 @@
 				    Uint32 callbackData,
 				    Uint32 returnCode)
 {
-  DropObjRecordPtr dropObjPtr;  
-  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
-
+  DropObjRecordPtr dropObjPtr;
   DictAbortConf * const conf = (DictAbortConf*)signal->getDataPtr();
+
+  ndbrequire(c_opDropObj.find(dropObjPtr, callbackData));
+  jam();
   conf->senderRef = reference();
   conf->senderData = dropObjPtr.p->m_senderData;
   sendSignal(dropObjPtr.p->m_senderRef, GSN_DICT_ABORT_CONF,
 	     signal, DictAbortConf::SignalLength, JBB);
-  
   c_opDropObj.release(dropObjPtr);
 }
 
 void 
-Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op){
+Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op)
+{
   /**
    * Put data into table record
    */
   SegmentedSectionPtr objInfoPtr;
+  jam();
   getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
   SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
 
@@ -15504,6 +15589,7 @@
     
     if(status != SimpleProperties::Eof)
     {
+      jam();
       op->m_errorCode = CreateTableRef::InvalidFormat;
       break;
     }
@@ -15512,6 +15598,7 @@
     {
       if(!fg.TS_ExtentSize)
       {
+        jam();
 	op->m_errorCode = CreateFilegroupRef::InvalidExtentSize;
 	break;
       }
@@ -15520,6 +15607,7 @@
     {
       if(!fg.LF_UndoBufferSize)
       {
+        jam();
 	op->m_errorCode = CreateFilegroupRef::InvalidUndoBufferSize;
 	break;
       }
@@ -15528,16 +15616,19 @@
     Uint32 len = strlen(fg.FilegroupName) + 1;
     Uint32 hash = Rope::hash(fg.FilegroupName, len);
     if(get_object(fg.FilegroupName, len, hash) != 0){
+      jam();
       op->m_errorCode = CreateTableRef::TableAlreadyExist;
       break;
     }
     
     if(!c_obj_pool.seize(obj_ptr)){
+      jam();
       op->m_errorCode = CreateTableRef::NoMoreTableRecords;
       break;
     }
     
     if(!c_filegroup_pool.seize(fg_ptr)){
+      jam();
       op->m_errorCode = CreateTableRef::NoMoreTableRecords;
       break;
     }
@@ -15547,6 +15638,7 @@
     {
       Rope name(c_rope_pool, obj_ptr.p->m_name);
       if(!name.assign(fg.FilegroupName, len, hash)){
+        jam();
 	op->m_errorCode = CreateTableRef::OutOfStringBuffer;
 	break;
       }
@@ -15560,6 +15652,7 @@
 
     switch(fg.FilegroupType){
     case DictTabInfo::Tablespace:
+    {
       //fg.TS_DataGrow = group.m_grow_spec;
       fg_ptr.p->m_tablespace.m_extent_size = fg.TS_ExtentSize;
       fg_ptr.p->m_tablespace.m_default_logfile_group_id = fg.TS_LogfileGroupId;
@@ -15567,22 +15660,28 @@
       Ptr<Filegroup> lg_ptr;
       if (!c_filegroup_hash.find(lg_ptr, fg.TS_LogfileGroupId))
       {
+        jam();
 	op->m_errorCode = CreateFilegroupRef::NoSuchLogfileGroup;
 	goto error;
       }
 
       if (lg_ptr.p->m_version != fg.TS_LogfileGroupVersion)
       {
+        jam();
 	op->m_errorCode = CreateFilegroupRef::InvalidFilegroupVersion;
 	goto error;
       }
       increase_ref_count(lg_ptr.p->m_obj_ptr_i);
       break;
+    }
     case DictTabInfo::LogfileGroup:
+    {
+      jam();
       fg_ptr.p->m_logfilegroup.m_undo_buffer_size = fg.LF_UndoBufferSize;
       fg_ptr.p->m_logfilegroup.m_files.init();
       //fg.LF_UndoGrow = ;
       break;
+    }
     default:
       ndbrequire(false);
     }
@@ -15617,13 +15716,14 @@
 }
 
 void
-Dbdict::create_fg_prepare_complete(Signal* signal, SchemaOp* op){
+Dbdict::create_fg_prepare_complete(Signal* signal, SchemaOp* op)
+{
   /**
    * CONTACT TSMAN LGMAN PGMAN 
    */
   CreateFilegroupImplReq* req = 
     (CreateFilegroupImplReq*)signal->getDataPtrSend();
-
+  jam();
   req->senderData = op->key;
   req->senderRef = reference();
   req->filegroup_id = op->m_obj_id;
@@ -15636,53 +15736,57 @@
   Uint32 len= 0;
   switch(op->m_obj_type){
   case DictTabInfo::Tablespace:
+  {
+    jam();
     ref = TSMAN_REF;
     len = CreateFilegroupImplReq::TablespaceLength;
     req->tablespace.extent_size = fg_ptr.p->m_tablespace.m_extent_size;
     req->tablespace.logfile_group_id = 
       fg_ptr.p->m_tablespace.m_default_logfile_group_id;
     break;
+  }
   case DictTabInfo::LogfileGroup:
+  {
+    jam();
     ref = LGMAN_REF;
     len = CreateFilegroupImplReq::LogfileGroupLength;
     req->logfile_group.buffer_size = 
       fg_ptr.p->m_logfilegroup.m_undo_buffer_size;
     break;
+  }
   default:
     ndbrequire(false);
   }
-  
   sendSignal(ref, GSN_CREATE_FILEGROUP_REQ, signal, len, JBB);
 }
 
 void
-Dbdict::execCREATE_FILEGROUP_REF(Signal* signal){
-  jamEntry();
-
+Dbdict::execCREATE_FILEGROUP_REF(Signal* signal)
+{
   CreateFilegroupImplRef * ref = (CreateFilegroupImplRef*)signal->getDataPtr();
-  
   CreateObjRecordPtr op_ptr;
+
+  jamEntry();
   ndbrequire(c_opCreateObj.find(op_ptr, ref->senderData));
   op_ptr.p->m_errorCode = ref->errorCode;
-
   execute(signal, op_ptr.p->m_callback, 0);  
 }  
 
 void
-Dbdict::execCREATE_FILEGROUP_CONF(Signal* signal){  
-  jamEntry();
-
+Dbdict::execCREATE_FILEGROUP_CONF(Signal* signal)
+{
   CreateFilegroupImplConf * rep = 
     (CreateFilegroupImplConf*)signal->getDataPtr();
-  
   CreateObjRecordPtr op_ptr;
+
+  jamEntry();
   ndbrequire(c_opCreateObj.find(op_ptr, rep->senderData));
-  
   execute(signal, op_ptr.p->m_callback, 0);  
 }
 
 void
-Dbdict::create_fg_abort_start(Signal* signal, SchemaOp* op){
+Dbdict::create_fg_abort_start(Signal* signal, SchemaOp* op)
+{
   CreateFilegroupImplReq* req = 
     (CreateFilegroupImplReq*)signal->getDataPtrSend();
 
@@ -15692,13 +15796,13 @@
     send_drop_fg(signal, op, DropFilegroupImplReq::Commit);
     return;
   }
-  
+  jam();  
   execute(signal, op->m_callback, 0);  
 }
 
 void
-Dbdict::create_fg_abort_complete(Signal* signal, SchemaOp* op){
-  
+Dbdict::create_fg_abort_complete(Signal* signal, SchemaOp* op)
+{
   if (op->m_obj_ptr_i != RNIL)
   {
     jam();
@@ -15708,12 +15812,13 @@
     release_object(fg_ptr.p->m_obj_ptr_i);
     c_filegroup_hash.release(fg_ptr);
   }
-  
+  jam();  
   execute(signal, op->m_callback, 0);
 }
 
 void 
-Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op){
+Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op)
+{
   /**
    * Put data into table record
    */
@@ -15733,6 +15838,7 @@
   
   do {
     if(status != SimpleProperties::Eof){
+      jam();
       op->m_errorCode = CreateFileRef::InvalidFormat;
       break;
     }
@@ -15740,34 +15846,53 @@
     // Get Filegroup
     FilegroupPtr fg_ptr;
     if(!c_filegroup_hash.find(fg_ptr, f.FilegroupId)){
+      jam();
       op->m_errorCode = CreateFileRef::NoSuchFilegroup;
       break;
     }
     
     if(fg_ptr.p->m_version != f.FilegroupVersion){
+      jam();
       op->m_errorCode = CreateFileRef::InvalidFilegroupVersion;
       break;
     }
 
     switch(f.FileType){
     case DictTabInfo::Datafile:
+    {
       if(fg_ptr.p->m_type != DictTabInfo::Tablespace)
+      {
+        jam();
 	op->m_errorCode = CreateFileRef::InvalidFileType;
+      }
+      jam();
       break;
+    }
     case DictTabInfo::Undofile:
+    {
       if(fg_ptr.p->m_type != DictTabInfo::LogfileGroup)
+      {
+        jam();
 	op->m_errorCode = CreateFileRef::InvalidFileType;
+      }
+      jam();
       break;
+    }
     default:
+      jam();
       op->m_errorCode = CreateFileRef::InvalidFileType;
     }
     
     if(op->m_errorCode)
+    {
+      jam();
       break;
+    }
 
     Uint32 len = strlen(f.FileName) + 1;
     Uint32 hash = Rope::hash(f.FileName, len);
     if(get_object(f.FileName, len, hash) != 0){
+      jam();
       op->m_errorCode = CreateFileRef::FilenameAlreadyExists;
       break;
     }
@@ -15778,6 +15903,7 @@
 	m_ctx.m_config.getOwnConfigIterator();
       if(!ndb_mgm_get_int_parameter(p, CFG_DB_DISCLESS, &dl) && dl)
       {
+        jam();
 	op->m_errorCode = CreateFileRef::NotSupportedWhenDiskless;
 	break;
       }
@@ -15785,11 +15911,13 @@
     
     // Loop through all filenames...
     if(!c_obj_pool.seize(obj_ptr)){
+      jam();
       op->m_errorCode = CreateTableRef::NoMoreTableRecords;
       break;
     }
     
     if (! c_file_pool.seize(filePtr)){
+      jam();
       op->m_errorCode = CreateFileRef::OutOfFileRecords;
       break;
     }
@@ -15799,6 +15927,7 @@
     {
       Rope name(c_rope_pool, obj_ptr.p->m_name);
       if(!name.assign(f.FileName, len, hash)){
+        jam();
 	op->m_errorCode = CreateTableRef::OutOfStringBuffer;
 	break;
       }
@@ -15806,10 +15935,14 @@
 
     switch(fg_ptr.p->m_type){
     case DictTabInfo::Tablespace:
+    {
+      jam();
       increase_ref_count(fg_ptr.p->m_obj_ptr_i);
       break;
+    }
     case DictTabInfo::LogfileGroup:
     {
+      jam();
       Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
       list.add(filePtr);
       break;
@@ -15853,37 +15986,46 @@
       c_obj_pool.release(obj_ptr);
     }
   }
-  
   execute(signal, op->m_callback, 0);
 }
 
 
 void
-Dbdict::create_file_prepare_complete(Signal* signal, SchemaOp* op){
+Dbdict::create_file_prepare_complete(Signal* signal, SchemaOp* op)
+{
   /**
    * CONTACT TSMAN LGMAN PGMAN 
    */
   CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
-
   FilePtr f_ptr;
-  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
-
   FilegroupPtr fg_ptr;
+
+  jam();
+  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
   ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
 
   req->senderData = op->key;
   req->senderRef = reference();
   switch(((OpCreateObj*)op)->m_restart){
   case 0:
+  {
+    jam();
     req->requestInfo = CreateFileImplReq::Create;
     break;
+  }
   case 1:
+  {
+    jam();
     req->requestInfo = CreateFileImplReq::Open;
     break;
+  }
   case 2:
+  {
+    jam();
     req->requestInfo = CreateFileImplReq::CreateForce;
     break;
   }
+  }
 	 
   req->file_id = f_ptr.p->key;
   req->filegroup_id = f_ptr.p->m_filegroup_id;
@@ -15895,14 +16037,20 @@
   Uint32 len= 0;
   switch(op->m_obj_type){
   case DictTabInfo::Datafile:
+  {
+    jam();
     ref = TSMAN_REF;
     len = CreateFileImplReq::DatafileLength;
     req->tablespace.extent_size = fg_ptr.p->m_tablespace.m_extent_size;
     break;
+  }
   case DictTabInfo::Undofile:
+  {
+    jam();
     ref = LGMAN_REF;
     len = CreateFileImplReq::UndofileLength;
     break;
+  }
   default:
     ndbrequire(false);
   }
@@ -15917,42 +16065,41 @@
 }
 
 void
-Dbdict::execCREATE_FILE_REF(Signal* signal){
-  jamEntry();
-
+Dbdict::execCREATE_FILE_REF(Signal* signal)
+{
   CreateFileImplRef * ref = (CreateFileImplRef*)signal->getDataPtr();
-  
   CreateObjRecordPtr op_ptr;
+
+  jamEntry();
   ndbrequire(c_opCreateObj.find(op_ptr, ref->senderData));
   op_ptr.p->m_errorCode = ref->errorCode;
-
   execute(signal, op_ptr.p->m_callback, 0);  
 }  
 
 void
-Dbdict::execCREATE_FILE_CONF(Signal* signal){  
-  jamEntry();
-
+Dbdict::execCREATE_FILE_CONF(Signal* signal)
+{
   CreateFileImplConf * rep = 
     (CreateFileImplConf*)signal->getDataPtr();
-  
   CreateObjRecordPtr op_ptr;
+
+  jamEntry();
   ndbrequire(c_opCreateObj.find(op_ptr, rep->senderData));
-  
   execute(signal, op_ptr.p->m_callback, 0);  
 }
 
 void
-Dbdict::create_file_commit_start(Signal* signal, SchemaOp* op){
+Dbdict::create_file_commit_start(Signal* signal, SchemaOp* op)
+{
   /**
    * CONTACT TSMAN LGMAN PGMAN 
    */
   CreateFileImplReq* req = (CreateFileImplReq*)signal->getDataPtrSend();
-
   FilePtr f_ptr;
-  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
-
   FilegroupPtr fg_ptr;
+
+  jam();
+  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
   ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
 
   req->senderData = op->key;
@@ -15966,15 +16113,20 @@
   Uint32 ref= 0;
   switch(op->m_obj_type){
   case DictTabInfo::Datafile:
+  {
+    jam();
     ref = TSMAN_REF;
     break;
+  }
   case DictTabInfo::Undofile:
+  {
+    jam();
     ref = LGMAN_REF;
     break;
+  }
   default:
     ndbrequire(false);
   }
-  
   sendSignal(ref, GSN_CREATE_FILE_REQ, signal, 
 	     CreateFileImplReq::CommitLength, JBB);
 }
@@ -15987,9 +16139,11 @@
   if (op->m_obj_ptr_i != RNIL)
   {
     FilePtr f_ptr;
+    FilegroupPtr fg_ptr;
+
+    jam();
     c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
     
-    FilegroupPtr fg_ptr;
     ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
     
     req->senderData = op->key;
@@ -16003,20 +16157,24 @@
     Uint32 ref= 0;
     switch(op->m_obj_type){
     case DictTabInfo::Datafile:
+    {
+      jam();
       ref = TSMAN_REF;
       break;
+    }
     case DictTabInfo::Undofile:
+    {
+      jam();
       ref = LGMAN_REF;
       break;
+    }
     default:
       ndbrequire(false);
     }
-    
     sendSignal(ref, GSN_CREATE_FILE_REQ, signal, 
 	       CreateFileImplReq::AbortLength, JBB);
     return;
   }
-
   execute(signal, op->m_callback, 0);
 }
 
@@ -16026,17 +16184,21 @@
   if (op->m_obj_ptr_i != RNIL)
   {
     FilePtr f_ptr;
-    c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
-    
     FilegroupPtr fg_ptr;
+
+    jam();
+    c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
     ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
-    
     switch(fg_ptr.p->m_type){
     case DictTabInfo::Tablespace:
+    {
+      jam();
       decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
       break;
+    }
     case DictTabInfo::LogfileGroup:
     {
+      jam();
       Local_file_list list(c_file_pool, fg_ptr.p->m_logfilegroup.m_files);
       list.remove(f_ptr);
       break;
@@ -16048,19 +16210,20 @@
     release_object(f_ptr.p->m_obj_ptr_i);
     c_file_hash.release(f_ptr);
   }
-  
   execute(signal, op->m_callback, 0);
 }
 
 void
 Dbdict::drop_file_prepare_start(Signal* signal, SchemaOp* op)
 {
+  jam();
   send_drop_file(signal, op, DropFileImplReq::Prepare);
 }
 
 void
 Dbdict::drop_undofile_prepare_start(Signal* signal, SchemaOp* op)
 {
+  jam();
   op->m_errorCode = DropFileRef::DropUndoFileNotSupported;
   execute(signal, op->m_callback, 0);  
 }
@@ -16068,6 +16231,7 @@
 void
 Dbdict::drop_file_commit_start(Signal* signal, SchemaOp* op)
 {
+  jam();
   send_drop_file(signal, op, DropFileImplReq::Commit);
 }
 
@@ -16075,21 +16239,21 @@
 Dbdict::drop_file_commit_complete(Signal* signal, SchemaOp* op)
 {
   FilePtr f_ptr;
-  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
-  
   FilegroupPtr fg_ptr;
-  ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
 
+  jam();
+  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
+  ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
   decrease_ref_count(fg_ptr.p->m_obj_ptr_i);
   release_object(f_ptr.p->m_obj_ptr_i);
   c_file_hash.release(f_ptr);
-
   execute(signal, op->m_callback, 0);
 }
 
 void
 Dbdict::drop_file_abort_start(Signal* signal, SchemaOp* op)
 {
+  jam();
   send_drop_file(signal, op, DropFileImplReq::Abort);
 }
 
@@ -16098,11 +16262,11 @@
 		       DropFileImplReq::RequestInfo type)
 {
   DropFileImplReq* req = (DropFileImplReq*)signal->getDataPtrSend();
-  
   FilePtr f_ptr;
-  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
-  
   FilegroupPtr fg_ptr;
+
+  jam();
+  c_file_pool.getPtr(f_ptr, op->m_obj_ptr_i);
   ndbrequire(c_filegroup_hash.find(fg_ptr, f_ptr.p->m_filegroup_id));
   
   req->senderData = op->key;
@@ -16116,29 +16280,34 @@
   Uint32 ref= 0;
   switch(op->m_obj_type){
   case DictTabInfo::Datafile:
+  {
+    jam();
     ref = TSMAN_REF;
     break;
+  }
   case DictTabInfo::Undofile:
+  {
+    jam();
     ref = LGMAN_REF;
     break;
+  }
   default:
     ndbrequire(false);
   }
-  
   sendSignal(ref, GSN_DROP_FILE_REQ, signal, 
 	     DropFileImplReq::SignalLength, JBB);
 }
 
 void
-Dbdict::execDROP_OBJ_REF(Signal* signal){
-  jamEntry();
-
+Dbdict::execDROP_OBJ_REF(Signal* signal)
+{
   DropObjRef * const ref = (DropObjRef*)signal->getDataPtr();
-  
   Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
   ndbrequire(c_Trans.find(trans_ptr, ref->senderData));
-  
   if(ref->errorCode != DropObjRef::NF_FakeErrorREF){
+    jam();
     trans_ptr.p->setErrorCode(ref->errorCode);
   }
   Uint32 node = refToNode(ref->senderRef);
@@ -16146,65 +16315,61 @@
 }
 
 void
-Dbdict::execDROP_OBJ_CONF(Signal* signal){
-  jamEntry();
-
+Dbdict::execDROP_OBJ_CONF(Signal* signal)
+{
   DropObjConf * const conf = (DropObjConf*)signal->getDataPtr();
-  
   Ptr<SchemaTransaction> trans_ptr;
+
+  jamEntry();
   ndbrequire(c_Trans.find(trans_ptr, conf->senderData));
   schemaOp_reply(signal, trans_ptr.p, refToNode(conf->senderRef));
 }
 
 void
-Dbdict::execDROP_FILE_REF(Signal* signal){
-  jamEntry();
-
+Dbdict::execDROP_FILE_REF(Signal* signal)
+{
   DropFileImplRef * ref = (DropFileImplRef*)signal->getDataPtr();
-  
   DropObjRecordPtr op_ptr;
+
+  jamEntry();
   ndbrequire(c_opDropObj.find(op_ptr, ref->senderData));
   op_ptr.p->m_errorCode = ref->errorCode;
-
   execute(signal, op_ptr.p->m_callback, 0);  
 }  
 
 void
-Dbdict::execDROP_FILE_CONF(Signal* signal){  
-  jamEntry();
-
+Dbdict::execDROP_FILE_CONF(Signal* signal)
+{
   DropFileImplConf * rep = 
     (DropFileImplConf*)signal->getDataPtr();
-  
   DropObjRecordPtr op_ptr;
+
+  jamEntry();
   ndbrequire(c_opDropObj.find(op_ptr, rep->senderData));
-  
   execute(signal, op_ptr.p->m_callback, 0);  
 }
 
 void
-Dbdict::execDROP_FILEGROUP_REF(Signal* signal){
-  jamEntry();
-
+Dbdict::execDROP_FILEGROUP_REF(Signal* signal)
+{
   DropFilegroupImplRef * ref = (DropFilegroupImplRef*)signal->getDataPtr();
-  
   DropObjRecordPtr op_ptr;
+
+  jamEntry();
   ndbrequire(c_opDropObj.find(op_ptr, ref->senderData));
   op_ptr.p->m_errorCode = ref->errorCode;
-
   execute(signal, op_ptr.p->m_callback, 0);  
 }  
 
 void
-Dbdict::execDROP_FILEGROUP_CONF(Signal* signal){  
-  jamEntry();
-
+Dbdict::execDROP_FILEGROUP_CONF(Signal* signal)
+{
   DropFilegroupImplConf * rep = 
     (DropFilegroupImplConf*)signal->getDataPtr();
-  
   DropObjRecordPtr op_ptr;
+
+  jamEntry();
   ndbrequire(c_opDropObj.find(op_ptr, rep->senderData));
-  
   execute(signal, op_ptr.p->m_callback, 0);  
 }
 
@@ -16217,11 +16382,13 @@
   DictObject * obj = c_obj_pool.getPtr(fg_ptr.p->m_obj_ptr_i);
   if (obj->m_ref_count)
   {
+    jam();
     op->m_errorCode = DropFilegroupRef::FilegroupInUse;
     execute(signal, op->m_callback, 0);  
   }
   else
   {
+    jam();
     send_drop_fg(signal, op, DropFilegroupImplReq::Prepare);
   }
 }
@@ -16233,7 +16400,7 @@
   c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
   if (op->m_obj_type == DictTabInfo::LogfileGroup)
   {
-    
+    jam(); 
     /**
      * Mark all undofiles as dropped
      */
@@ -16242,6 +16409,7 @@
     XSchemaFile * xsf = &c_schemaFile[c_schemaRecord.schemaPage != 0];
     for(list.first(filePtr); !filePtr.isNull(); list.next(filePtr))
     {
+      jam();
       Uint32 objId = filePtr.p->key;
       SchemaFile::TableEntry * tableEntry = getTableEntry(xsf, objId);
       tableEntry->m_tableState = SchemaFile::DROP_TABLE_COMMITTED;
@@ -16254,13 +16422,14 @@
   else if(op->m_obj_type == DictTabInfo::Tablespace)
   {
     FilegroupPtr lg_ptr;
+    jam();
     ndbrequire(c_filegroup_hash.
 	       find(lg_ptr, 
 		    fg_ptr.p->m_tablespace.m_default_logfile_group_id));
     
     decrease_ref_count(lg_ptr.p->m_obj_ptr_i);
   }
-  
+  jam(); 
   send_drop_fg(signal, op, DropFilegroupImplReq::Commit);
 }
 
@@ -16269,16 +16438,17 @@
 {
   FilegroupPtr fg_ptr;
   c_filegroup_pool.getPtr(fg_ptr, op->m_obj_ptr_i);
-  
+
+  jam();
   release_object(fg_ptr.p->m_obj_ptr_i);
   c_filegroup_hash.release(fg_ptr);
-
   execute(signal, op->m_callback, 0);
 }
 
 void
 Dbdict::drop_fg_abort_start(Signal* signal, SchemaOp* op)
 {
+  jam();
   send_drop_fg(signal, op, DropFilegroupImplReq::Abort);
 }
 
@@ -16301,16 +16471,20 @@
   Uint32 ref= 0;
   switch(op->m_obj_type){
   case DictTabInfo::Tablespace:
+  {
+    jam();
     ref = TSMAN_REF;
     break;
+  }
   case DictTabInfo::LogfileGroup:
+  {
+    jam();
     ref = LGMAN_REF;
     break;
+  }
   default:
     ndbrequire(false);
   }
-  
   sendSignal(ref, GSN_DROP_FILEGROUP_REQ, signal, 
 	     DropFilegroupImplReq::SignalLength, JBB);
 }
-

--- 1.103/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2007-03-02 16:48:15 +01:00
+++ 1.104/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2007-03-06 18:54:04 +01:00
@@ -7437,7 +7437,7 @@
     jam();
     ndbassert(tabPtr.p->method == TabRecord::USER_DEFINED);
     fragId= hashValue;
-    if (fragId >= tabPtr.p->totalfragments)
+    if (fragId >= tabPtr.p->totalfragments || !req->distr_key_indicator)
     {
       jam();
       conf->zero= 1; //Indicate error;
@@ -7450,13 +7450,14 @@
   Uint32 sig2 = (nodeCount - 1) + 
     (fragPtr.p->distributionKey << 16);
   conf->zero = 0;
-  conf->reqinfo = sig2;
   conf->fragId = fragId;
+  conf->reqinfo = sig2;
 }//Dbdih::execDIGETNODESREQ()
 
 Uint32 Dbdih::extractNodeInfo(const Fragmentstore * fragPtr, Uint32 nodes[]) 
 {
   Uint32 nodeCount = 0;
+  nodes[0] = nodes[1] = nodes[2] = nodes[3] = 0;
   for (Uint32 i = 0; i < fragPtr->fragReplicas; i++) {
     jam();
     NodeRecordPtr nodePtr;

--- 1.134/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2007-03-02 16:48:18 +01:00
+++ 1.135/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2007-03-06 18:54:05 +01:00
@@ -3419,30 +3419,44 @@
   regTcPtr->applOprec = sig4;
 
   regTcPtr->commitAckMarker = RNIL;
-  if(LqhKeyReq::getMarkerFlag(Treqinfo)){
-    jam();
-    
+  if (LqhKeyReq::getMarkerFlag(Treqinfo))
+  {
+    struct CommitAckMarker check;
     CommitAckMarkerPtr markerPtr;
-    m_commitAckMarkerHash.seize(markerPtr);
-    if(markerPtr.i == RNIL){
-      noFreeRecordLab(signal, lqhKeyReq, ZNO_FREE_MARKER_RECORDS_ERROR);
-      return;
+    jam();
+    check.transid1 = regTcPtr->transid[0];
+    check.transid2 = regTcPtr->transid[1];
+
+    if (m_commitAckMarkerHash.find(markerPtr, check))
+    {
+      /*
+        A commit ack marker was already placed here for this transaction.
+        We increase the reference count to ensure we don't remove the
+        commit ack marker prematurely.
+      */
+      markerPtr.p->reference_count++;
+    }
+    else
+    {
+      m_commitAckMarkerHash.seize(markerPtr);
+      if (markerPtr.i == RNIL)
+      {
+        noFreeRecordLab(signal, lqhKeyReq, ZNO_FREE_MARKER_RECORDS_ERROR);
+        return;
+      }
+      markerPtr.p->transid1 = sig1;
+      markerPtr.p->transid2 = sig2;
+      markerPtr.p->apiRef   = sig3;
+      markerPtr.p->apiOprec = sig4;
+      const NodeId tcNodeId  = refToNode(sig5);
+      markerPtr.p->tcNodeId = tcNodeId;
+      markerPtr.p->reference_count = 1;
+      m_commitAckMarkerHash.add(markerPtr);
     }
-    markerPtr.p->transid1 = sig1;
-    markerPtr.p->transid2 = sig2;
-    markerPtr.p->apiRef   = sig3;
-    markerPtr.p->apiOprec = sig4;
-    const NodeId tcNodeId  = refToNode(sig5);
-    markerPtr.p->tcNodeId = tcNodeId;
     
-    CommitAckMarkerPtr tmp;
-#if defined VM_TRACE || defined ERROR_INSERT
 #ifdef MARKER_TRACE
     ndbout_c("Add marker[%.8x %.8x]", markerPtr.p->transid1, markerPtr.p->transid2);
 #endif
-    ndbrequire(!m_commitAckMarkerHash.find(tmp, * markerPtr.p));
-#endif
-    m_commitAckMarkerHash.add(markerPtr);
     regTcPtr->commitAckMarker = markerPtr.i;
   } 
   
@@ -6674,6 +6688,28 @@
 /*                                                                           */
 /*THIS PART IS USED AT ERRORS THAT CAUSE ABORT OF TRANSACTION.               */
 /* ------------------------------------------------------------------------- */
+void
+Dblqh::remove_commit_marker(TcConnectionrec * const regTcPtr)
+{
+  CommitAckMarker *tmp;
+  Uint32 commitAckMarker = regTcPtr->commitAckMarker;
+  regTcPtr->commitAckMarker = RNIL;
+  if (commitAckMarker == RNIL)
+    return;
+  jam();
+  tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
+#ifdef MARKER_TRACE
+  ndbout_c("Ab2 marker[%.8x %.8x]", tmp->transid1, tmp->transid2);
+#endif
+  ndbrequire(tmp->reference_count > 0);
+  tmp->reference_count--;
+  if (tmp->reference_count == 0)
+  {
+    jam();
+    m_commitAckMarkerHash.release(commitAckMarker);
+  }
+}
+
 /* ***************************************************>> */
 /*  ABORT: Abort transaction in connection. Sender TC.   */
 /*  This is the normal protocol (See COMMIT)             */
@@ -6751,21 +6787,7 @@
   }//if
   regTcPtr->abortState = TcConnectionrec::ABORT_FROM_TC;
 
-  const Uint32 commitAckMarker = regTcPtr->commitAckMarker;
-  if(commitAckMarker != RNIL)
-  {
-    jam();
-#ifdef MARKER_TRACE
-    {
-      CommitAckMarkerPtr tmp;
-      m_commitAckMarkerHash.getPtr(tmp, commitAckMarker);
-      ndbout_c("Ab2 marker[%.8x %.8x]", tmp.p->transid1, tmp.p->transid2);
-    }
-#endif
-    m_commitAckMarkerHash.release(commitAckMarker);
-    regTcPtr->commitAckMarker = RNIL;
-  }
-
+  remove_commit_marker(regTcPtr);
   TRACE_OP(regTcPtr, "ABORT");
 
   abortStateHandlerLab(signal);
@@ -7098,24 +7120,9 @@
 void Dblqh::abortCommonLab(Signal* signal) 
 {
   TcConnectionrec * const regTcPtr = tcConnectptr.p;
-  const Uint32 commitAckMarker = regTcPtr->commitAckMarker;
   const Uint32 activeCreat = regTcPtr->activeCreat;
-  if (commitAckMarker != RNIL)
-  {
-    /**
-     * There is no NR ongoing and we have a marker
-     */
-    jam();
-#ifdef MARKER_TRACE
-    {
-      CommitAckMarkerPtr tmp;
-      m_commitAckMarkerHash.getPtr(tmp, commitAckMarker);
-      ndbout_c("Abo marker[%.8x %.8x]", tmp.p->transid1, tmp.p->transid2);
-    }
-#endif
-    m_commitAckMarkerHash.release(commitAckMarker);
-    regTcPtr->commitAckMarker = RNIL;
-  }
+
+  remove_commit_marker(regTcPtr);
 
   if (unlikely(activeCreat == Fragrecord::AC_NR_COPY))
   {
@@ -18614,13 +18621,14 @@
     for(m_commitAckMarkerHash.first(iter); iter.curr.i != RNIL;
 	m_commitAckMarkerHash.next(iter)){
       infoEvent("CommitAckMarker: i = %d (0x%x, 0x%x)"
-		" ApiRef: 0x%x apiOprec: 0x%x TcNodeId: %d",
+		" ApiRef: 0x%x apiOprec: 0x%x TcNodeId: %d, ref_count: %d",
 		iter.curr.i,
 		iter.curr.p->transid1,
 		iter.curr.p->transid2,
 		iter.curr.p->apiRef,
 		iter.curr.p->apiOprec,
-		iter.curr.p->tcNodeId);
+		iter.curr.p->tcNodeId,
+                iter.curr.p->reference_count);
     }
   }
 

--- 1.49/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2007-03-02 16:48:19 +01:00
+++ 1.50/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2007-03-06 18:54:05 +01:00
@@ -626,7 +626,7 @@
     ApiConnectRecord(ArrayPool<TcFiredTriggerData> & firedTriggerPool,
 		     ArrayPool<TcIndexOperation> & seizedIndexOpPool):
       theFiredTriggers(firedTriggerPool),
-      isIndexOp(false),
+      isIndexOp(FALSE),
       theSeizedIndexOperations(seizedIndexOpPool) 
     {}
     
@@ -636,7 +636,6 @@
     ConnectionState apiConnectstate;
     UintR transid[2];
     UintR firstTcConnect;
-    NdbNodeBitmask m_transaction_nodes; 
     
     //---------------------------------------------------
     // Second 16 byte cache line. Hot variables.
@@ -672,26 +671,39 @@
     //---------------------------------------------------
     UintR lastTcConnect;
     UintR lqhkeyreqrec;
-    AbortState abortState;
     Uint32 buddyPtr;
+    union {
+      UintR apiScanRec;
+      UintR commitAckMarker;
+    };
+
+    Uint32 no_commit_ack_markers;
+    ReturnSignal returnsignal;
+    AbortState abortState;
+    Uint8 indexOpReturn;
+    Uint8 triggerPending; // Used to mark waiting for a CONTINUEB
+
     Uint8 m_exec_flag;
-    Uint8 unused2;
+    Uint8 isIndexOp;      // Used to mark on-going TcKeyReq as indx table access
     Uint8 takeOverRec;
     Uint8 currentReplicaNo;
+    Uint8 m_commit_ack_marker_received;
+
+    Uint8 tcindxrec;
+    Uint8 timeOutCounter;
     
+    Uint16 returncode;
+    Uint16 takeOverInd;
     //---------------------------------------------------
     // Error Handling variables. If cache line 32 bytes
     // ensures that cache line is still only read in
     // early phases.
     //---------------------------------------------------
-    union {
-      UintR apiScanRec;
-      UintR commitAckMarker;
-    };
     UintR currentTcConnect;
     BlockReference tcBlockref;
-    Uint16 returncode;
-    Uint16 takeOverInd;
+    UintR failureNr;
     
     //---------------------------------------------------
     // Second 64 byte cache line. Third 16 byte cache line
@@ -706,14 +718,8 @@
     // timeOutCounter is used waiting for ABORTCONF, COMMITCONF
     // and COMPLETECONF
     //---------------------------------------------------
-    UintR failureNr;
-    Uint8 tcindxrec;
-    ReturnSignal returnsignal;
-    Uint8 timeOutCounter;
-    
     UintR tcSendArray[6];
+    NdbNodeBitmask m_transaction_nodes; 
     
     // Trigger data
     
@@ -722,12 +728,9 @@
      */  
     DLFifoList<TcFiredTriggerData> theFiredTriggers;
     
-    bool triggerPending; // Used to mark waiting for a CONTINUEB
     
     // Index data
     
-    Uint8 isIndexOp;      // Used to mark on-going TcKeyReq as indx table access
-    bool indexOpReturn;
     UintR noIndexOp;     // No outstanding index ops
 
     // Index op return context
@@ -1825,8 +1828,7 @@
     Uint32 prevHash;
     Uint32 apiConnectPtr;
     Uint16 apiNodeId;
-    Uint16 noOfLqhs;
-    Uint16 lqhNodeId[MAX_REPLICAS];
+    NdbNodeBitmask m_commit_ack_marker_nodes; 
 
     inline bool equal(const CommitAckMarker & p) const {
       return ((p.transid1 == transid1) && (p.transid2 == transid2));

--- 1.137/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2007-03-02 16:48:22 +01:00
+++ 1.138/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2007-03-06 19:36:44 +01:00
@@ -21,6 +21,7 @@
 #include <ndb_limits.h>
 #include <my_sys.h>
 
+#include <signaldata/DiGetNodes.hpp>
 #include <signaldata/EventReport.hpp>
 #include <signaldata/TcKeyReq.hpp>
 #include <signaldata/TcKeyConf.hpp>
@@ -282,7 +283,7 @@
     ApiConnectRecordPtr transPtr;
     transPtr.i = Tdata0;
     ptrCheckGuard(transPtr, capiConnectFilesize, apiConnectRecord);
-    transPtr.p->triggerPending = false;
+    transPtr.p->triggerPending = FALSE;
     executeTriggers(signal, &transPtr);
     return;
   case TcContinueB::DelayTCKEYCONF:
@@ -2376,6 +2377,8 @@
   regApiPtr->lqhkeyreqrec = 0;
   regApiPtr->tckeyrec = 0;
   regApiPtr->tcindxrec = 0;
+  regApiPtr->m_commit_ack_marker_received = 0;
+  regApiPtr->no_commit_ack_markers = 0;
   regApiPtr->failureNr = TfailureNr;
   regApiPtr->transid[0] = Ttransid0;
   regApiPtr->transid[1] = Ttransid1;
@@ -2386,7 +2389,7 @@
   // Trigger data
   releaseFiredTriggerData(&regApiPtr->theFiredTriggers),
   // Index data
-  regApiPtr->indexOpReturn = false;
+  regApiPtr->indexOpReturn = FALSE;
   regApiPtr->noIndexOp = 0;
   if(releaseIndexOperations)
     releaseAllSeizedIndexOperations(regApiPtr);
@@ -2433,7 +2436,7 @@
   regTcPtr->noReceivedTriggers = 0;
   regTcPtr->triggerExecutionCount = 0;
   regTcPtr->triggeringOperation = RNIL;
-  regTcPtr->isIndexOp = false;
+  regTcPtr->isIndexOp = FALSE;
   regTcPtr->indexOp = RNIL;
   regTcPtr->currentIndexId = RNIL;
 
@@ -2533,7 +2536,7 @@
 
   Uint8 isIndexOp = regApiPtr->isIndexOp;
   bool isIndexOpReturn = regApiPtr->indexOpReturn;
-  regApiPtr->isIndexOp = false; // Reset marker
+  regApiPtr->isIndexOp = FALSE; // Reset marker
   regApiPtr->m_exec_flag |= TexecFlag;
   switch (regApiPtr->apiConnectstate) {
   case CS_CONNECTED:{
@@ -2815,29 +2818,38 @@
     Uint32 TreadCount = c_counters.creadCount;
     jam();
     c_counters.creadCount = TreadCount + 1;
-  } else {
-    if(regApiPtr->commitAckMarker == RNIL){
-      jam();
-      CommitAckMarkerPtr tmp;
-      if(!m_commitAckMarkerHash.seize(tmp)){
-        TCKEY_abort(signal, 56);
-        return;
-      } else {
-        regTcPtr->commitAckMarker = tmp.i;
-        regApiPtr->commitAckMarker = tmp.i;
-        tmp.p->transid1      = tcKeyReq->transId1;
-        tmp.p->transid2      = tcKeyReq->transId2;
-        tmp.p->apiNodeId     = refToNode(regApiPtr->ndbapiBlockref);
-        tmp.p->apiConnectPtr = TapiIndex;
-        tmp.p->noOfLqhs      = 0;
+  }
+  else
+  {
+    if (!regApiPtr->m_commit_ack_marker_received)
+    {
+      if(regApiPtr->commitAckMarker == RNIL)
+      {
+        jam();
+        CommitAckMarkerPtr tmp;
+        if(!m_commitAckMarkerHash.seize(tmp)){
+          TCKEY_abort(signal, 56);
+          return;
+        } else {
+          regTcPtr->commitAckMarker = tmp.i;
+          regApiPtr->commitAckMarker = tmp.i;
+          tmp.p->transid1      = tcKeyReq->transId1;
+          tmp.p->transid2      = tcKeyReq->transId2;
+          tmp.p->apiNodeId     = refToNode(regApiPtr->ndbapiBlockref);
+          tmp.p->apiConnectPtr = TapiIndex;
+          tmp.p->m_commit_ack_marker_nodes.clear();
 #if defined VM_TRACE || defined ERROR_INSERT
-	{
-	  CommitAckMarkerPtr check;
-	  ndbrequire(!m_commitAckMarkerHash.find(check, *tmp.p));
-	}
+	  {
+	    CommitAckMarkerPtr check;
+	    ndbrequire(!m_commitAckMarkerHash.find(check, *tmp.p));
+          }
 #endif
-        m_commitAckMarkerHash.add(tmp);
+          m_commitAckMarkerHash.add(tmp);
+        }
       }
+      else
+        regTcPtr->commitAckMarker = regApiPtr->commitAckMarker;
+      regApiPtr->no_commit_ack_markers++;
     }
     
     UintR TwriteCount = c_counters.cwriteCount;
@@ -2861,8 +2873,8 @@
     default:
       TCKEY_abort(signal, 9);
       return;
-    }//switch
-  }//if
+    }
+  }
   
   Uint32 TabortOption = TcKeyReq::getAbortOption(Treqinfo);
   regTcPtr->m_execAbortOption = TabortOption;
@@ -2943,12 +2955,6 @@
 
   hash(signal); /* NOW IT IS TIME TO CALCULATE THE HASH VALUE*/
   
-  if (unlikely(terrorCode))
-  {
-    releaseAtErrorLab(signal);
-    return;
-  }
-
   CacheRecord * const regCachePtr = cachePtr.p;
   TcConnectRecord * const regTcPtr = tcConnectptr.p;
   ApiConnectRecord * const regApiPtr = apiConnectptr.p;
@@ -2956,7 +2962,6 @@
   UintR TtcTimer = ctcTimer;
   UintR ThashValue = thashValue;
   UintR TdistrHashValue = tdistrHashValue;
-  UintR TdihConnectptr = regTcPtr->dihConnectptr;
   UintR Ttableref = regCachePtr->tableref;
   
   TableRecordPtr localTabptr;
@@ -2974,13 +2979,10 @@
   setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
   regCachePtr->hashValue = ThashValue;
 
-  signal->theData[0] = TdihConnectptr;
-  signal->theData[1] = Ttableref;
-  signal->theData[2] = TdistrHashValue;
-  signal->theData[3] = 0;
-  signal->theData[4] = 0;
-  signal->theData[5] = 0;
-  signal->theData[6] = 0;
+  DiGetNodesReq * const req = (DiGetNodesReq *)&signal->theData[0];
+  req->tableId = Ttableref;
+  req->hashValue = TdistrHashValue;
+  req->distr_key_indicator = regCachePtr->distributionKeyIndicator;
 
   /*-------------------------------------------------------------*/
   /* FOR EFFICIENCY REASONS WE AVOID THE SIGNAL SENDING HERE AND */
@@ -2990,7 +2992,8 @@
   /* TO DIH IN TRAFFIC IT SHOULD BE OK (3% OF THE EXECUTION TIME */
   /* IS SPENT IN DIH AND EVEN LESS IN REPLICATED NDB.            */
   /*-------------------------------------------------------------*/
-  EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal, 3);
+  EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal,
+                 DiGetNodesReq::SignalLength);
   UintR TerrorIndicator = signal->theData[0];
   jamEntry();
   if (TerrorIndicator != 0) {
@@ -3010,12 +3013,13 @@
   /* DIGETNODESCONF >*/
   /* ***************>*/
 
-  UintR Tdata1 = signal->theData[1];
-  UintR Tdata2 = signal->theData[2];
-  UintR Tdata3 = signal->theData[3];
-  UintR Tdata4 = signal->theData[4];
-  UintR Tdata5 = signal->theData[5];
-  UintR Tdata6 = signal->theData[6];
+  const DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
+  UintR Tdata1 = conf->fragId;
+  UintR Tdata2 = conf->reqinfo;
+  UintR Tdata3 = conf->nodes[0];
+  UintR Tdata4 = conf->nodes[1];
+  UintR Tdata5 = conf->nodes[2];
+  UintR Tdata6 = conf->nodes[3];
 
   regCachePtr->fragmentid = Tdata1;
   tnodeinfo = Tdata2;
@@ -3234,22 +3238,7 @@
    * Bit 28 == 0 since readLenAi can only be set after reading in LQH.
    * ----------------------------------------------------------------------- */
   //LqhKeyReq::setAPIVersion(Tdata10, regCachePtr->apiVersionNo);
-  Uint32 commitAckMarker = regTcPtr->commitAckMarker;
-  const Uint32 noOfLqhs = regTcPtr->noOfNodes;
-  if(commitAckMarker != RNIL){
-    jam();
-    LqhKeyReq::setMarkerFlag(Tdata10, 1);
-
-    CommitAckMarker * tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
-    
-    /**
-     * Populate LQH array
-     */
-    tmp->noOfLqhs = noOfLqhs;
-    for(Uint32 i = 0; i<noOfLqhs; i++){
-      tmp->lqhNodeId[i] = regTcPtr->tcNodedata[i];
-    }
-  }
+  LqhKeyReq::setMarkerFlag(Tdata10, regTcPtr->commitAckMarker != RNIL ? 1 : 0);
   
   /* ************************************************************> */
   /* NO READ LENGTH SENT FROM TC. SEQUENTIAL NUMBER IS 1 AND IT    */
@@ -3393,6 +3382,7 @@
       return;
     }//if
     if (anAttrBufIndex < TattrbufFilesize) {
+  jam();
       AttrbufRecord * const regAttrPtr = &localAttrbufRecord[anAttrBufIndex];
       anAttrBufIndex = regAttrPtr->attrbuf[ZINBUF_NEXT];
       sendAttrinfo(signal,
@@ -3534,7 +3524,7 @@
   regTcPtr->tcConnectstate = OS_CONNECTED;
   regTcPtr->nextTcConnect = TfirstfreeTcConnect;
   regTcPtr->apiConnect = RNIL;
-  regTcPtr->isIndexOp = false;
+  regTcPtr->isIndexOp = FALSE;
   regTcPtr->indexOp = RNIL;
   cfirstfreeTcConnect = TtcConnectptrIndex;
   c_counters.cconcurrentOp = TconcurrentOp - 1;
@@ -3736,8 +3726,20 @@
     return;
   }//if
 
+  Uint32 commitAckMarker = regTcPtr->commitAckMarker;
   setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
 
+  if(commitAckMarker != RNIL){
+    const Uint32 noOfLqhs = regTcPtr->noOfNodes;
+    CommitAckMarker * tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
+    jam();
+    regApiPtr->m_commit_ack_marker_received = TRUE;
+    /**
+     * Populate LQH array
+     */
+    for(Uint32 i = 0; i<noOfLqhs; i++)
+      tmp->m_commit_ack_marker_nodes.set(regTcPtr->tcNodedata[i]);
+  }
   if (regTcPtr->isIndexOp) {
     jam();
     // This was an internal TCKEYREQ
@@ -3820,7 +3822,7 @@
 void Dbtc::setupIndexOpReturn(ApiConnectRecord* regApiPtr,
 			      TcConnectRecord* regTcPtr) 
 {
-  regApiPtr->indexOpReturn = true;
+  regApiPtr->indexOpReturn = TRUE;
   regApiPtr->indexOp = regTcPtr->indexOp;
   regApiPtr->clientData = regTcPtr->clientData;
   regApiPtr->attrInfoLen = regTcPtr->attrInfoLen;
@@ -3965,7 +3967,7 @@
     tcKeyConf->operations[0].attrInfoLen = regApiPtr->attrInfoLen;
     Uint32 sigLen = TcKeyConf::StaticLength + TcKeyConf::OperationLength;
     EXECUTE_DIRECT(DBTC, GSN_TCKEYCONF, signal, sigLen);
-    regApiPtr->indexOpReturn = false;
+    regApiPtr->indexOpReturn = FALSE;
     if (TopWords == 0) {
       jam();
       return; // No queued TcKeyConf
@@ -4221,8 +4223,8 @@
   cfirstfreeApiConnectCopy = locApiConnectptr.p->nextApiConnect;
   locApiConnectptr.p->nextApiConnect = RNIL;
   regApiPtr->apiCopyRecord = locApiConnectptr.i;
-  regApiPtr->triggerPending = false;
-  regApiPtr->isIndexOp = false;
+  regApiPtr->triggerPending = FALSE;
+  regApiPtr->isIndexOp = FALSE;
 }//Dbtc::seizeApiConnectCopy()
 
 void Dbtc::execDIVERIFYCONF(Signal* signal) 
@@ -4824,16 +4826,17 @@
 }
 
 void
-Dbtc::sendRemoveMarkers(Signal* signal, const CommitAckMarker * marker){
+Dbtc::sendRemoveMarkers(Signal* signal, const CommitAckMarker * marker)
+{
   jam();
-  const Uint32 noOfLqhs = marker->noOfLqhs;
   const Uint32 transId1 = marker->transid1;
   const Uint32 transId2 = marker->transid2;
   
-  for(Uint32 i = 0; i<noOfLqhs; i++){
+  for(Uint32 node_id = 1; node_id < MAX_NDB_NODES; node_id++)
+  {
     jam();
-    const NodeId nodeId = marker->lqhNodeId[i];
-    sendRemoveMarker(signal, nodeId, transId1, transId2);
+    if (marker->m_commit_ack_marker_nodes.get(node_id))
+      sendRemoveMarker(signal, node_id, transId1, transId2);
   }
 }
 
@@ -5135,7 +5138,6 @@
 	}
       }
       
-      Uint32 marker = regTcPtr->commitAckMarker;
       markOperationAborted(regApiPtr, regTcPtr);
       
       if(regApiPtr->apiConnectstate == CS_ABORTING){
@@ -5155,16 +5157,6 @@
 	return;
       }//if
 
-      if (marker != RNIL){
-	/**
-	 * This was an insert/update/delete/write which failed
-	 *   that contained the marker
-	 * Currently unsupported to place new marker
-	 */
-	TCKEY_abort(signal, 49);
-	return;
-      }
-      
       /* Only ref in certain situations */
       {
 	const Uint32 opType = regTcPtr->operation;
@@ -5248,13 +5240,18 @@
   const Uint32 commitAckMarker = regTcPtr->commitAckMarker;
   if (regApiPtr->commitAckMarker == RNIL)
     ndbassert(commitAckMarker == RNIL);
-  if (commitAckMarker != RNIL)
-    ndbassert(regApiPtr->commitAckMarker != RNIL);
   if(commitAckMarker != RNIL){
     jam();
-    m_commitAckMarkerHash.release(commitAckMarker);
+    ndbassert(regApiPtr->commitAckMarker != RNIL);
+    ndbrequire(regApiPtr->no_commit_ack_markers > 0);
+    regApiPtr->no_commit_ack_markers--;
     regTcPtr->commitAckMarker = RNIL;
-    regApiPtr->commitAckMarker = RNIL;
+    if (regApiPtr->no_commit_ack_markers == 0)
+    {
+      regApiPtr->commitAckMarker = RNIL;
+      regApiPtr->m_commit_ack_marker_received = FALSE;
+      m_commitAckMarkerHash.release(commitAckMarker);
+    }
   }
 }
 
@@ -7764,12 +7761,7 @@
 	  const Uint32 marker = apiConnectptr.p->commitAckMarker;
           if(marker != RNIL){
 	    jam();
-
-            CommitAckMarkerPtr tmp;
-            tmp.i = marker;
-            tmp.p = m_commitAckMarkerHash.getPtr(tmp.i);
-            
-            m_commitAckMarkerHash.release(tmp);
+            m_commitAckMarkerHash.release(marker);
             apiConnectptr.p->commitAckMarker = RNIL;
           }
           
@@ -8222,8 +8214,7 @@
     tmp.p->transid1      = ttransid1;
     tmp.p->transid2      = ttransid2;
     tmp.p->apiNodeId     = refToNode(tapplRef);
-    tmp.p->noOfLqhs      = 1;
-    tmp.p->lqhNodeId[0]  = tnodeid;
+    tmp.p->m_commit_ack_marker_nodes.set(tnodeid);
     tmp.p->apiConnectPtr = apiConnectptr.i;
 
 #if defined VM_TRACE || defined ERROR_INSERT
@@ -8371,13 +8362,14 @@
 /*----------------------------------------------------------*/
 void Dbtc::updateApiStateFail(Signal* signal) 
 {
-  if(LqhTransConf::getMarkerFlag(treqinfo)){
-    jam();
+  if(LqhTransConf::getMarkerFlag(treqinfo))
+  {
+    CommitAckMarkerPtr tmp;
     const Uint32 marker = apiConnectptr.p->commitAckMarker;
-    if(marker == RNIL){
+    if(marker == RNIL)
+    {
       jam();
 
-      CommitAckMarkerPtr tmp;
       m_commitAckMarkerHash.seize(tmp);
       ndbrequire(tmp.i != RNIL);
       
@@ -8385,8 +8377,6 @@
       tmp.p->transid1      = ttransid1;
       tmp.p->transid2      = ttransid2;
       tmp.p->apiNodeId     = refToNode(tapplRef);
-      tmp.p->noOfLqhs      = 1;
-      tmp.p->lqhNodeId[0]  = tnodeid;
       tmp.p->apiConnectPtr = apiConnectptr.i;
 #if defined VM_TRACE || defined ERROR_INSERT
       {
@@ -8397,16 +8387,10 @@
       m_commitAckMarkerHash.add(tmp);
     } else {
       jam();
-      
-      CommitAckMarkerPtr tmp;
       tmp.i = marker;
       tmp.p = m_commitAckMarkerHash.getPtr(marker);
-
-      const Uint32 noOfLqhs = tmp.p->noOfLqhs;
-      ndbrequire(noOfLqhs < MAX_REPLICAS);
-      tmp.p->lqhNodeId[noOfLqhs] = tnodeid;
-      tmp.p->noOfLqhs = (noOfLqhs + 1);
     }
+    tmp.p->m_commit_ack_marker_nodes.set(tnodeid);
   }
 
   switch (ttransStatus) {
@@ -9060,14 +9044,14 @@
   }
   else 
   {
-    signal->theData[0] = tcConnectptr.p->dihConnectptr;
-    signal->theData[1] = tabPtr.i;
-    signal->theData[2] = cachePtr.p->distributionKey;
-    EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal, 3);
-    UintR TerrorIndicator = signal->theData[0];
-    Uint32 Tsingle_scan_count = c_counters.c_single_scan_count;
-    Uint32 Tsingle_scan_no_distr = c_counters.c_single_scan_no_distr;
-    Uint32 TownNode = getOwnNodeId();
+    DiGetNodesReq * const req = (DiGetNodesReq *)&signal->theData[0];
+    const DiGetNodesConf * const get_conf = (DiGetNodesConf *)&signal->theData[0];
+    req->tableId = tabPtr.i;
+    req->hashValue = cachePtr.p->distributionKey;
+    req->distr_key_indicator = TRUE;
+    EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal,
+                   DiGetNodesReq::SignalLength);
+    UintR TerrorIndicator = get_conf->zero;
     jamEntry();
     if (TerrorIndicator != 0) {
       DihFragCountRef * const ref = (DihFragCountRef*)signal->getDataPtr();
@@ -9077,11 +9061,15 @@
       return;
     }
     
-    UintR Tdata1 = signal->theData[1];
+    Uint32 TownNode = getOwnNodeId();
+    Uint32 Tsingle_scan_count = c_counters.c_single_scan_count;
+    Uint32 Tsingle_scan_no_distr = c_counters.c_single_scan_no_distr;
+    UintR TfragId = get_conf->fragId;
+    Uint32 TfirstNode = get_conf->nodes[0];
     c_counters.c_single_scan_count = Tsingle_scan_count + 1;
-    if (TownNode == signal->theData[3])
+    scanptr.p->scanNextFragId = TfragId;
+    if (TownNode == TfirstNode)
       c_counters.c_single_scan_no_distr = Tsingle_scan_no_distr + 1;
-    scanptr.p->scanNextFragId = Tdata1;
     DihFragCountConf * const conf = (DihFragCountConf*)signal->getDataPtr();
     conf->m_connectionData = tcConnectptr.i;
     conf->m_fragmentCount = 1; // Frag count
@@ -10092,8 +10080,8 @@
     apiConnectptr.p->commitAckMarker = RNIL;
     apiConnectptr.p->firstTcConnect = RNIL;
     apiConnectptr.p->lastTcConnect = RNIL;
-    apiConnectptr.p->triggerPending = false;
-    apiConnectptr.p->isIndexOp = false;
+    apiConnectptr.p->triggerPending = FALSE;
+    apiConnectptr.p->isIndexOp = FALSE;
     apiConnectptr.p->accumulatingIndexOp = RNIL;
     apiConnectptr.p->executingIndexOp = RNIL;
     apiConnectptr.p->buddyPtr = RNIL;
@@ -10120,8 +10108,8 @@
       apiConnectptr.p->commitAckMarker = RNIL;
       apiConnectptr.p->firstTcConnect = RNIL;
       apiConnectptr.p->lastTcConnect = RNIL;
-      apiConnectptr.p->triggerPending = false;
-      apiConnectptr.p->isIndexOp = false;
+      apiConnectptr.p->triggerPending = FALSE;
+      apiConnectptr.p->isIndexOp = FALSE;
       apiConnectptr.p->accumulatingIndexOp = RNIL;
       apiConnectptr.p->executingIndexOp = RNIL;
       apiConnectptr.p->buddyPtr = RNIL;
@@ -10148,8 +10136,8 @@
     apiConnectptr.p->commitAckMarker = RNIL;
     apiConnectptr.p->firstTcConnect = RNIL;
     apiConnectptr.p->lastTcConnect = RNIL;
-    apiConnectptr.p->triggerPending = false;
-    apiConnectptr.p->isIndexOp = false;
+    apiConnectptr.p->triggerPending = FALSE;
+    apiConnectptr.p->isIndexOp = FALSE;
     apiConnectptr.p->accumulatingIndexOp = RNIL;
     apiConnectptr.p->executingIndexOp = RNIL;
     apiConnectptr.p->buddyPtr = RNIL;
@@ -10604,8 +10592,8 @@
     apiConnectptr.p->nextApiConnect = RNIL;
     setApiConTimer(apiConnectptr.i, 0, __LINE__);
     apiConnectptr.p->apiConnectstate = CS_CONNECTED; /* STATE OF CONNECTION */
-    apiConnectptr.p->triggerPending = false;
-    apiConnectptr.p->isIndexOp = false;
+    apiConnectptr.p->triggerPending = FALSE;
+    apiConnectptr.p->isIndexOp = FALSE;
   } else {
     jam();
     terrorCode = ZNO_FREE_API_CONNECTION;
@@ -10633,7 +10621,7 @@
   ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
   cfirstfreeTcConnect = tcConnectptr.p->nextTcConnect;
   c_counters.cconcurrentOp++;
-  tcConnectptr.p->isIndexOp = false;
+  tcConnectptr.p->isIndexOp = FALSE;
 }//Dbtc::seizeTcConnect()
 
 void Dbtc::seizeTcConnectFail(Signal* signal) 
@@ -10803,16 +10791,15 @@
     for(m_commitAckMarkerHash.first(iter); iter.curr.i != RNIL;
         m_commitAckMarkerHash.next(iter)){
       infoEvent("CommitAckMarker: i = %d (0x%x, 0x%x)"
-                " Api: %d Lghs(%d): %d %d %d %d bucket = %d",
+                " Api: %d %x %x %x %x bucket = %d",
                 iter.curr.i,
                 iter.curr.p->transid1,
                 iter.curr.p->transid2,
                 iter.curr.p->apiNodeId,
-                iter.curr.p->noOfLqhs,
-                iter.curr.p->lqhNodeId[0],
-                iter.curr.p->lqhNodeId[1],
-                iter.curr.p->lqhNodeId[2],
-                iter.curr.p->lqhNodeId[3],
+                iter.curr.p->m_commit_ack_marker_nodes.getWord(0),
+                iter.curr.p->m_commit_ack_marker_nodes.getWord(1),
+                iter.curr.p->m_commit_ack_marker_nodes.getWord(2),
+                iter.curr.p->m_commit_ack_marker_nodes.getWord(3),
                 iter.bucket);
     }
   }
@@ -12913,7 +12900,7 @@
       jam();
       if (!regApiPtr->triggerPending) {
         jam();
-        regApiPtr->triggerPending = true;
+        regApiPtr->triggerPending = TRUE;
         signal->theData[0] = TcContinueB::TRIGGER_PENDING;
         signal->theData[1] = transPtr->i;
         sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);

--- 1.415/sql/ha_ndbcluster.cc	2007-03-03 19:50:16 +01:00
+++ 1.416/sql/ha_ndbcluster.cc	2007-03-06 19:36:44 +01:00
@@ -264,7 +264,8 @@
   return error;
 }
 
-int execute_no_commit_ignore_no_key(ha_ndbcluster *h, NdbTransaction *trans)
+int execute_no_commit_ignore_no_key(ha_ndbcluster *h, NdbTransaction *trans,
+                                    bool &ignored_error)
 {
   if (trans->execute(NdbTransaction::NoCommit,
                      NdbOperation::AO_IgnoreError,
@@ -276,14 +277,25 @@
       err.classification != NdbError::ConstraintViolation &&
       err.classification != NdbError::NoDataFound)
     return -1;
-
+  if (err.classification != NdbError::NoError)
+    ignored_error= TRUE;
   return 0;
 }
 
 inline
+int execute_no_commit_ignore_error(ha_ndbcluster *h, NdbTransaction *trans,
+                                   bool force_release,
+                                   bool &ignored_error)
+{
+  h->release_completed_operations(trans, force_release);
+  return execute_no_commit_ignore_no_key(h, trans, ignored_error);
+}
+
+inline
 int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans,
 		      bool force_release)
 {
+  bool not_used;
 #ifdef NOT_USED
   int m_batch_execute= 0;
   if (m_batch_execute)
@@ -291,7 +303,7 @@
 #endif
   h->release_completed_operations(trans, force_release);
   return h->m_ignore_no_key ?
-    execute_no_commit_ignore_no_key(h,trans) :
+    execute_no_commit_ignore_no_key(h,trans, not_used) :
     trans->execute(NdbTransaction::NoCommit,
 		   NdbOperation::AbortOnError,
 		   h->m_force_send);
@@ -1581,7 +1593,8 @@
 }
 
 
-int ha_ndbcluster::set_primary_key_from_record(NdbOperation *op, const byte *record)
+int ha_ndbcluster::set_primary_key_from_record(NdbOperation *op,
+                                               const byte *record)
 {
   KEY* key_info= table->key_info + table_share->primary_key;
   KEY_PART_INFO* key_part= key_info->key_part;
@@ -1893,6 +1906,22 @@
 }
 
 
+bool ha_ndbcluster::is_key_updated(KEY_PART_INFO *key_part_info,
+                                   uint key_parts)
+{
+  uint i;
+  DBUG_ENTER("is_key_updated");
+
+  for (i= 0; i < key_parts; i++, key_part_info++)
+  {
+    if (bitmap_is_set(table->write_set, key_part_info->fieldnr-1))
+    {
+      DBUG_RETURN(TRUE);
+    }
+  }
+  DBUG_RETURN(FALSE);
+}
+
 /*
  * Peek to check if any rows already exist with conflicting
  * primary key or unique index values
@@ -1947,16 +1976,19 @@
    */
   KEY* key_info;
   KEY_PART_INFO *key_part, *end;
+  uint key_parts;
   for (i= 0, key_info= table->key_info; i < table->s->keys; i++, key_info++)
   {
+    key_part= key_info->key_part;
+    key_parts= key_info->key_parts;
     if (i != table->s->primary_key &&
-        key_info->flags & HA_NOSAME)
+        key_info->flags & HA_NOSAME &&
+        is_key_updated(key_part, key_parts))
     {
-      // A unique index is defined on table
+      // A unique index is defined on table and it's being updated
       NdbIndexOperation *iop;
       const NDBINDEX *unique_index = m_index[i].unique_index;
-      key_part= key_info->key_part;
-      end= key_part + key_info->key_parts;
+      end= key_part + key_parts;
       if (!(iop= trans->getNdbIndexOperation(unique_index, m_table)) ||
           iop->readTuple(lm) != 0)
         ERR_RETURN(trans->getNdbError());
@@ -2878,9 +2910,10 @@
   uint32 old_part_id= 0, new_part_id= 0;
   int error;
   longlong func_value;
-  bool pk_update= (table_share->primary_key != MAX_KEY &&
-                   key_cmp(table_share->primary_key, old_data, new_data));
-
+  bool ignored_error= FALSE;
+  bool pk_update= (!m_read_before_write_removal_possible &&
+                   table_share->primary_key != MAX_KEY &&
+		   key_cmp(table_share->primary_key, old_data, new_data));
   DBUG_ENTER("update_row");
 
   DBUG_ASSERT(trans);
@@ -2969,6 +3002,7 @@
       DBUG_RETURN(insert_res);
     }
     DBUG_PRINT("info", ("delete+insert succeeded"));
+    m_rows_updated++;
     DBUG_RETURN(0);
   }
 
@@ -2992,31 +3026,46 @@
       cursor->setPartitionId(new_part_id);
   }
   else
-  {  
-    if (!(op= trans->getNdbOperation(m_table)) ||
-        op->updateTuple() != 0)
-      ERR_RETURN(trans->getNdbError());  
-    
-    if (m_user_defined_partitioning)
-      op->setPartitionId(new_part_id);
-    if (table_share->primary_key == MAX_KEY) 
-    {
-      // This table has no primary key, use "hidden" primary key
-      DBUG_PRINT("info", ("Using hidden key"));
-      
-      // Require that the PK for this record has previously been 
-      // read into m_ref
-      DBUG_DUMP("key", m_ref, NDB_HIDDEN_PRIMARY_KEY_LENGTH);
-      
-      if (set_hidden_key(op, table->s->fields, m_ref))
-        ERR_RETURN(op->getNdbError());
-    } 
-    else 
+  {
+    if (m_read_before_write_removal_possible &&
+        active_index != table_share->primary_key)
     {
       int res;
-      if ((res= set_primary_key_from_record(op, old_data)))
+      if (!(op= trans->getNdbIndexOperation(
+                                   m_index[active_index].unique_index,
+                                   m_table)) ||
+          op->updateTuple() != 0)
+        ERR_RETURN(trans->getNdbError());  
+      if ((res= set_index_key_from_record(op, old_data, active_index)))
         DBUG_RETURN(res);
     }
+    else
+    {
+      if (!(op= trans->getNdbOperation(m_table)) ||
+          op->updateTuple() != 0)
+        ERR_RETURN(trans->getNdbError());  
+    
+      if (m_user_defined_partitioning)
+        op->setPartitionId(new_part_id);
+      if (table_share->primary_key == MAX_KEY) 
+      {
+        // This table has no primary key, use "hidden" primary key
+        DBUG_PRINT("info", ("Using hidden key"));
+      
+        // Require that the PK for this record has previously been 
+        // read into m_ref
+        DBUG_DUMP("key", m_ref, NDB_HIDDEN_PRIMARY_KEY_LENGTH);
+      
+        if (set_hidden_key(op, table->s->fields, m_ref))
+          ERR_RETURN(op->getNdbError());
+      } 
+      else 
+      {
+        int res;
+        if ((res= set_primary_key_from_record(op, old_data)))
+          DBUG_RETURN(res);
+      }
+    }
   }
 
   m_rows_changed++;
@@ -3047,11 +3096,16 @@
     op->setValue(no_fields, part_func_value);
   }
   // Execute update operation
-  if (!cursor && execute_no_commit(this,trans,FALSE) != 0) {
+  if (!cursor &&
+      ((m_read_before_write_removal_possible ?
+        execute_no_commit_ignore_error(this,trans,FALSE, ignored_error) :
+        execute_no_commit(this,trans,FALSE)) != 0))
+  {
     no_uncommitted_rows_execute_failure();
     DBUG_RETURN(ndb_err(trans));
   }
-  
+  if (!ignored_error)
+    m_rows_updated++;
   DBUG_RETURN(0);
 }
 
@@ -3068,6 +3122,7 @@
   NdbOperation *op;
   uint32 part_id;
   int error;
+  bool ignored_error= FALSE;
   DBUG_ENTER("delete_row");
   m_write_op= TRUE;
 
@@ -3103,41 +3158,62 @@
     no_uncommitted_rows_update(-1);
 
     if (!m_primary_key_update)
+    {
       // If deleting from cursor, NoCommit will be handled in next_result
+      m_rows_deleted++;
       DBUG_RETURN(0);
+    }
   }
   else
   {
+    if (m_read_before_write_removal_possible &&
+        active_index != table_share->primary_key)
+    {
+      if (!(op=trans->getNdbIndexOperation(
+                         m_index[active_index].unique_index,
+                         m_table)) || 
+          op->deleteTuple() != 0)
+        ERR_RETURN(trans->getNdbError());
+      if ((error= set_index_key_from_record(op, record, active_index)))
+        DBUG_RETURN(error);
+    }
+    else
+    {
+      if (!(op=trans->getNdbOperation(m_table)) || 
+          op->deleteTuple() != 0)
+        ERR_RETURN(trans->getNdbError());
     
-    if (!(op=trans->getNdbOperation(m_table)) || 
-        op->deleteTuple() != 0)
-      ERR_RETURN(trans->getNdbError());
-    
-    if (m_user_defined_partitioning)
-      op->setPartitionId(part_id);
+      if (m_user_defined_partitioning)
+        op->setPartitionId(part_id);
 
-    no_uncommitted_rows_update(-1);
+      no_uncommitted_rows_update(-1);
     
-    if (table_share->primary_key == MAX_KEY) 
-    {
-      // This table has no primary key, use "hidden" primary key
-      DBUG_PRINT("info", ("Using hidden key"));
+      if (table_share->primary_key == MAX_KEY) 
+      {
+        // This table has no primary key, use "hidden" primary key
+        DBUG_PRINT("info", ("Using hidden key"));
       
-      if (set_hidden_key(op, table->s->fields, m_ref))
-        ERR_RETURN(op->getNdbError());
-    } 
-    else 
-    {
-      if ((error= set_primary_key_from_record(op, record)))
-        DBUG_RETURN(error);
+        if (set_hidden_key(op, table->s->fields, m_ref))
+          ERR_RETURN(op->getNdbError());
+      } 
+      else 
+      {
+        if ((error= set_primary_key_from_record(op, record)))
+          DBUG_RETURN(error);
+      }
     }
   }
 
   // Execute delete operation
-  if (execute_no_commit(this,trans,FALSE) != 0) {
+  if ((m_read_before_write_removal_possible ?
+       execute_no_commit_ignore_error(this,trans,FALSE, ignored_error) :
+       execute_no_commit(this,trans,FALSE)) != 0)
+  {
     no_uncommitted_rows_execute_failure();
     DBUG_RETURN(ndb_err(trans));
   }
+  if (!m_primary_key_update && !ignored_error)
+    m_rows_deleted++;
   DBUG_RETURN(0);
 }
   
@@ -3363,6 +3439,11 @@
     and no sub-sequent call to unlock_row()
   */
   m_lock_tuple= FALSE;
+  if (table_share->primary_key == MAX_KEY &&
+      m_use_partition_function)
+    include_partition_fields_in_used_fields(
+            m_part_info->full_part_field_array,
+            table->read_set);
   DBUG_RETURN(0);
 }
 
@@ -3916,6 +3997,11 @@
         stats.auto_increment_value= (ulonglong)auto_increment_value64;
     }
   }
+  if (flag & HA_STATUS_WRITTEN_ROWS)
+  {
+    stats.rows_updated= m_rows_updated;
+    stats.rows_deleted= m_rows_deleted;
+  }
 
   if(result == -1)
     result= HA_ERR_NO_CONNECTION;
@@ -3980,6 +4066,41 @@
   DBUG_RETURN(0);
 }
 
+void ha_ndbcluster::column_bitmaps_signal(uint sig_type)
+{
+  DBUG_ENTER("column_bitmaps_signal");
+  DBUG_PRINT("enter", ("read_set: 0x%lx  write_set: 0x%lx", (long) table->read_set,
+                      (long) table->write_set));
+  if (sig_type & HA_COMPLETE_TABLE_READ_BITMAP)
+  {
+    bitmap_copy(&m_save_read_set, table->read_set);
+  }
+  DBUG_VOID_RETURN;
+}
+
+bool ha_ndbcluster::read_before_write_removal_possible(List<Item> *fields,
+                                                       List<Item> *values)
+{
+  DBUG_ENTER("read_before_write_removal_possible");
+  m_write_op= TRUE;
+  if (table_share->primary_key != MAX_KEY &&
+      !bitmap_is_overlapping(table->write_set, &m_primary_key_fields) &&
+      !uses_blob_value())
+  {
+    /*
+      Not a primary key update. We also check that the SET expressions
+      are all constant expressions, non-constant expressions requires
+      more work on handling push-down of expressions to NDB kernel.
+    */
+    if (!values || check_constant_expressions(values))
+    {
+      DBUG_PRINT("info", ("read_before_write_removal_possible TRUE"));
+      m_read_before_write_removal_possible= TRUE;
+    }
+  }
+  DBUG_RETURN(m_read_before_write_removal_possible);
+}
+
 
 int ha_ndbcluster::reset()
 {
@@ -3992,6 +4113,8 @@
   */
   if (m_part_info)
     bitmap_set_all(&m_part_info->used_partitions);
+  m_read_before_write_removal_possible= FALSE;
+  m_rows_updated= m_rows_deleted= 0;
   DBUG_RETURN(0);
 }
 
@@ -6089,6 +6212,7 @@
   m_has_unique_index(FALSE),
   m_primary_key_update(FALSE),
   m_ignore_no_key(FALSE),
+  m_read_before_write_removal_possible(FALSE),
   m_rows_to_insert((ha_rows) 1),
   m_rows_inserted((ha_rows) 0),
   m_bulk_insert_rows((ha_rows) 1024),
@@ -6185,6 +6309,8 @@
 {
   int res;
   KEY *key;
+  KEY_PART_INFO *key_part_info;
+  uint key_parts, i;
   DBUG_ENTER("ha_ndbcluster::open");
   DBUG_PRINT("enter", ("name: %s  mode: %d  test_if_locked: %d",
                        name, mode, test_if_locked));
@@ -6194,10 +6320,20 @@
     primary key to be written in the ref variable
   */
   
+  if (bitmap_init(&m_save_read_set, NULL,
+                  table_share->fields, TRUE))
+    DBUG_RETURN(1);
   if (table_share->primary_key != MAX_KEY) 
   {
     key= table->key_info+table_share->primary_key;
+    key_part_info= key->key_part;
+    key_parts= key->key_parts;
     ref_length= key->key_length;
+    if (bitmap_init(&m_primary_key_fields, NULL,
+                    table_share->fields, TRUE))
+      DBUG_RETURN(1);
+    for (i= 0; i < key_parts; i++, key_part_info++)
+      bitmap_set_bit(&m_primary_key_fields, key_part_info->fieldnr-1);
   }
   else // (table_share->primary_key == MAX_KEY) 
   {
@@ -6212,7 +6348,10 @@
   // Init table lock structure 
   /* ndb_share reference handler */
   if (!(m_share=get_share(name, table)))
+  {
+    close();
     DBUG_RETURN(1);
+  }
   DBUG_PRINT("NDB_SHARE", ("%s handler  use_count: %u",
                            m_share->key, m_share->use_count));
   thr_lock_data_init(&m_share->lock,&m_lock,(void*) 0);
@@ -6225,11 +6364,10 @@
     /* ndb_share reference handler free */
     DBUG_PRINT("NDB_SHARE", ("%s handler free  use_count: %u",
                              m_share->key, m_share->use_count));
-    free_share(&m_share);
-    m_share= 0;
+    close();
     DBUG_RETURN(HA_ERR_NO_CONNECTION);
   }
-  
+
   res= get_metadata(name);
   if (!res)
   {
@@ -6243,13 +6381,18 @@
     if(!res)
       res= info(HA_STATUS_CONST);
   }
+  if (res)
+  {
+    close();
+    DBUG_RETURN(res);
+  }
 
 #ifdef HAVE_NDB_BINLOG
   if (!ndb_binlog_tables_inited && ndb_binlog_running)
     table->db_stat|= HA_READ_ONLY;
 #endif
 
-  DBUG_RETURN(res);
+  DBUG_RETURN(0);
 }
 
 /*
@@ -6316,12 +6459,17 @@
   DBUG_ENTER("close");
   THD *thd= current_thd;
   Ndb *ndb= thd ? check_ndb_in_thd(thd) : g_ndb;
-  /* ndb_share reference handler free */
-  DBUG_PRINT("NDB_SHARE", ("%s handler free  use_count: %u",
-                           m_share->key, m_share->use_count));
-  free_share(&m_share);
+  if (m_share)
+  {
+    /* ndb_share reference handler free */
+    DBUG_PRINT("NDB_SHARE", ("%s handler free  use_count: %u",
+                             m_share->key, m_share->use_count));
+    free_share(&m_share);
+  }
   m_share= 0;
   release_metadata(thd, ndb);
+  if (table_share->primary_key != MAX_KEY)
+    bitmap_free(&m_primary_key_fields);
   DBUG_RETURN(0);
 }
 
@@ -8408,6 +8556,53 @@
   DBUG_RETURN(FALSE);
 }
 
+void ha_ndbcluster::check_read_before_write_removal()
+{
+  DBUG_ENTER("check_read_before_write_removal");
+  /*
+    We are doing an update or delete and it is possible that we
+    can ignore the read before the update or delete. This is
+    possible here since we are not updating the primary key and
+    if the index used is unique or primary and if the WHERE clause
+    only involves fields from this index we are ok to go. At this
+    moment we can only updates where all SET expressions are
+    constants. Thus no read set will come from SET expressions.
+  */
+  if (table_share->primary_key == active_index)
+  {
+    if (!bitmap_is_subset(&m_save_read_set, &m_primary_key_fields))
+      m_read_before_write_removal_possible= FALSE;
+  }
+  else
+  {
+    KEY *key= table->key_info+active_index;
+    if (!(key->flags & HA_NOSAME))
+    {
+      /* Optimisation not applicable on non-unique indexes */
+      m_read_before_write_removal_possible= FALSE;
+    }
+    else
+    {
+      /* Unique index bitmaps are built on the fly */
+      KEY_PART_INFO *key_part_info= key->key_part;
+      uint key_parts= key->key_parts;
+      MY_BITMAP index_map;
+      uint32 index_bitmap[NDB_MAX_ATTRIBUTES_IN_TABLE/32];
+      uint32 i;
+
+      bitmap_init(&index_map, (my_bitmap_map*)index_bitmap,
+                  table_share->fields, FALSE);
+      for (i= 0; i < key_parts; i++, key_part_info++)
+        bitmap_set_bit(&index_map, key_part_info->fieldnr-1);
+      if (!bitmap_is_subset(&m_save_read_set, &index_map))
+        m_read_before_write_removal_possible= FALSE;
+    }
+  }
+  DBUG_PRINT("info", ("m_read_before_write_removal_possible = %d",
+                       m_read_before_write_removal_possible));
+  DBUG_VOID_RETURN;
+}
+
 int
 ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
                                       KEY_MULTI_RANGE *ranges, 
@@ -8479,12 +8674,17 @@
   NdbOperation::LockMode lm= 
     (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
   bool need_pk = (lm == NdbOperation::LM_Read);
+  bool any_real_read= FALSE;
   const NDBTAB *tab= m_table;
   const NDBINDEX *unique_idx= m_index[active_index].unique_index;
   const NDBINDEX *idx= m_index[active_index].index; 
   NdbIndexScanOperation* scanOp= 0;
   const NdbOperation* lastOp= m_active_trans ?
          m_active_trans->getLastDefinedOperation() : 0;
+
+  if (m_read_before_write_removal_possible)
+    check_read_before_write_removal();
+
   for (; multi_range_curr<multi_range_end && curr+reclength <= end_of_buffer; 
        multi_range_curr++)
   {
@@ -8539,16 +8739,25 @@
       // else fall through
     case PRIMARY_KEY_INDEX:
     {
-      multi_range_curr->range_flag |= UNIQUE_RANGE;
-      if ((op= m_active_trans->getNdbOperation(tab)) && 
-          !op->readTuple(lm) && 
-          !set_primary_key(op, multi_range_curr->start_key.key) &&
-          !define_read_attrs(curr, op) &&
-          (!m_user_defined_partitioning ||
-           (op->setPartitionId(part_spec.start_part), TRUE)))
-        curr += reclength;
+      if (!m_read_before_write_removal_possible)
+      {
+        any_real_read= TRUE;
+        multi_range_curr->range_flag |= UNIQUE_RANGE;
+        if ((op= m_active_trans->getNdbOperation(tab)) && 
+            !op->readTuple(lm) && 
+            !set_primary_key(op, multi_range_curr->start_key.key) &&
+            !define_read_attrs(curr, op) &&
+            (!m_user_defined_partitioning ||
+             (op->setPartitionId(part_spec.start_part), TRUE)))
+          curr += reclength;
+        else
+          ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
+      }
       else
-        ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
+      {
+        multi_range_curr->range_flag|= READ_KEY_FROM_RANGE;
+        continue;
+      }
       break;
     }
     break;
@@ -8561,19 +8770,29 @@
       // else fall through
     case UNIQUE_INDEX:
     {
-      multi_range_curr->range_flag |= UNIQUE_RANGE;
-      if ((op= m_active_trans->getNdbIndexOperation(unique_idx, tab)) && 
-          !op->readTuple(lm) && 
-          !set_index_key(op, key_info, multi_range_curr->start_key.key) &&
-          !define_read_attrs(curr, op))
-        curr += reclength;
+      if (!m_read_before_write_removal_possible)
+      {
+        any_real_read= TRUE;
+        multi_range_curr->range_flag |= UNIQUE_RANGE;
+        if ((op= m_active_trans->getNdbIndexOperation(unique_idx, tab)) && 
+            !op->readTuple(lm) && 
+            !set_index_key(op, key_info, multi_range_curr->start_key.key) &&
+            !define_read_attrs(curr, op))
+          curr += reclength;
+        else
+          ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
+      }
       else
-        ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
+      {
+        multi_range_curr->range_flag|= READ_KEY_FROM_RANGE;
+        continue;
+      }
       break;
     }
     case ORDERED_INDEX: {
   range:
       multi_range_curr->range_flag &= ~(uint)UNIQUE_RANGE;
+      any_real_read= TRUE;
       if (scanOp == 0)
       {
         if (m_multi_cursor)
@@ -8639,13 +8858,17 @@
   /**
    * Set first operation in multi range
    */
-  m_current_multi_operation= 
-    lastOp ? lastOp->next() : m_active_trans->getFirstDefinedOperation();
-  if (!(res= execute_no_commit_ie(this, m_active_trans,true)))
+  if (any_real_read)
+  {
+    m_current_multi_operation= 
+      lastOp ? lastOp->next() : m_active_trans->getFirstDefinedOperation();
+  }
+  if (!any_real_read || 
+      !(res= execute_no_commit_ie(this, m_active_trans,true)))
   {
     m_multi_range_defined= multi_range_curr;
-    multi_range_curr= ranges;
     m_multi_range_result_ptr= (byte*)buffer->buffer;
+    multi_range_curr= ranges;
     DBUG_RETURN(read_multi_range_next(found_range_p));
   }
   ERR_RETURN(m_active_trans->getNdbError());
@@ -8660,6 +8883,7 @@
 int
 ha_ndbcluster::read_multi_range_next(KEY_MULTI_RANGE ** multi_range_found_p)
 {
+  uint range_flag;
   DBUG_ENTER("ha_ndbcluster::read_multi_range_next");
   if (m_disable_multi_read)
   {
@@ -8675,9 +8899,20 @@
   for (;multi_range_curr < m_multi_range_defined; multi_range_curr++)
   {
     DBUG_MULTI_RANGE(12);
-    if (multi_range_curr->range_flag & SKIP_RANGE)
+    range_flag= multi_range_curr->range_flag;
+    if (range_flag & SKIP_RANGE)
       continue;
-    if (multi_range_curr->range_flag & UNIQUE_RANGE)
+    if (range_flag & READ_KEY_FROM_RANGE)
+    {
+      DBUG_PRINT("info", ("using read before write removal optimisation"));
+      KEY* key_info= table->key_info + active_index;
+      key_restore(table->record[0], multi_range_curr->start_key.key,
+                  key_info, key_info->key_length);
+      table->status= 0;     
+      multi_range_curr++;
+      DBUG_RETURN(0);
+    }
+    if (range_flag & UNIQUE_RANGE)
     {
       if (op->getNdbError().code == 0)
       {

--- 1.174/sql/ha_ndbcluster.h	2007-03-02 16:47:58 +01:00
+++ 1.175/sql/ha_ndbcluster.h	2007-03-06 19:36:44 +01:00
@@ -683,6 +683,9 @@
     { return HA_POS_ERROR; }
   int info(uint);
   void get_dynamic_partition_info(PARTITION_INFO *stat_info, uint part_id);
+  bool read_before_write_removal_possible(List<Item> *fields,
+                                          List<Item> *values);
+  void column_bitmaps_signal(uint sig_type);
   uint32 calculate_key_hash_value(Field **field_array);
   int extra(enum ha_extra_function operation);
   int extra_opt(enum ha_extra_function operation, ulong cache_size);
@@ -801,6 +804,8 @@
                                       Ndb *ndb, NdbEventOperation *pOp,
                                       NDB_SHARE *share);
 
+  void check_read_before_write_removal();
+  bool is_key_updated(KEY_PART_INFO *key_part_info, uint key_parts);
   static int delete_table(ha_ndbcluster *h, Ndb *ndb,
 			  const char *path,
 			  const char *db,
@@ -949,9 +954,14 @@
                                    byte *buf);
 
   friend int execute_commit(ha_ndbcluster*, NdbTransaction*);
-  friend int execute_no_commit_ignore_no_key(ha_ndbcluster*, NdbTransaction*);
+  friend int execute_no_commit_ignore_no_key(ha_ndbcluster*, NdbTransaction*,
+                                             bool &ignored_error);
   friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*, bool);
-  friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*, bool);
+  friend int execute_no_commit_ignore_error(ha_ndbcluster*, NdbTransaction*,
+                                            bool force_release,
+                                            bool &ignored_error);
+  friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*,
+                                  bool force_release);
 
   NdbTransaction *m_active_trans;
   NdbScanOperation *m_active_cursor;
@@ -966,6 +976,8 @@
   NDB_SHARE *m_share;
   NDB_INDEX_DATA  m_index[MAX_KEY];
   THD_NDB_SHARE *m_thd_ndb_share;
+  MY_BITMAP m_primary_key_fields;
+  MY_BITMAP m_save_read_set;
   // NdbRecAttr has no reference to blob
   NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
   byte m_ref[NDB_HIDDEN_PRIMARY_KEY_LENGTH];
@@ -982,9 +994,12 @@
   bool m_primary_key_update;
   bool m_write_op;
   bool m_ignore_no_key;
+  bool m_read_before_write_removal_possible;
   ha_rows m_rows_to_insert; // TODO: merge it with handler::estimation_rows_to_insert?
   ha_rows m_rows_inserted;
   ha_rows m_bulk_insert_rows;
+  ha_rows m_rows_updated;
+  ha_rows m_rows_deleted;
   ha_rows m_rows_changed;
   bool m_bulk_insert_not_flushed;
   ha_rows m_ops_pending;

--- 1.84/sql/ha_partition.cc	2007-03-02 16:47:58 +01:00
+++ 1.85/sql/ha_partition.cc	2007-03-06 18:54:01 +01:00
@@ -2928,7 +2928,8 @@
   uint32 part_id;
   DBUG_ENTER("ha_partition::rnd_init");
 
-  include_partition_fields_in_used_fields();
+  include_partition_fields_in_used_fields(m_part_field_array,
+                                          table->read_set);
   
   /* Now we see what the index of our first important partition is */
   DBUG_PRINT("info", ("m_part_info->used_partitions: 0x%lx",
@@ -3242,7 +3243,8 @@
   m_start_key.length= 0;
   m_ordered= sorted;
   m_curr_key_info= table->key_info+inx;
-  include_partition_fields_in_used_fields();
+  include_partition_fields_in_used_fields(m_part_field_array,
+                                          table->read_set);
   file= m_file;
   do
   {
@@ -4133,35 +4135,6 @@
   return_top_record(buf);
   DBUG_PRINT("info", ("Record returned from partition %d", m_top_entry));
   DBUG_RETURN(0);
-}
-
-
-/*
-  Set fields in partition functions in read set for underlying handlers
-
-  SYNOPSIS
-    include_partition_fields_in_used_fields()
-
-  RETURN VALUE
-    NONE
-
-  DESCRIPTION
-    Some handlers only read fields as specified by the bitmap for the
-    read set. For partitioned handlers we always require that the
-    fields of the partition functions are read such that we can
-    calculate the partition id to place updated and deleted records.
-*/
-
-void ha_partition::include_partition_fields_in_used_fields()
-{
-  Field **ptr= m_part_field_array;
-  DBUG_ENTER("ha_partition::include_partition_fields_in_used_fields");
-
-  do
-  {
-    bitmap_set_bit(table->read_set, (*ptr)->field_index);
-  } while (*(++ptr));
-  DBUG_VOID_RETURN;
 }
 
 

--- 1.33/sql/ha_partition.h	2007-01-24 16:11:27 +01:00
+++ 1.34/sql/ha_partition.h	2007-03-06 18:54:01 +01:00
@@ -133,7 +133,7 @@
   PARTITION_SHARE *share;               /* Shared lock info */
 
 public:
-  virtual void set_part_info(partition_info *part_info)
+  virtual void set_part_info(partition_info *part_info, bool early)
   {
      m_part_info= part_info;
      m_is_sub_partitioned= part_info->is_sub_partitioned();
@@ -518,7 +518,8 @@
     underlying handlers must have the same implementation for it to work.
   */
   virtual uint8 table_cache_type();
-
+  /* Calculate hash value for PARTITION BY KEY tables.  */
+  uint32 calculate_key_hash_value(Field **field_array);
   /*
     -------------------------------------------------------------------------
     MODULE print messages

--- 1.100/sql/sql_partition.cc	2007-03-02 18:44:22 +01:00
+++ 1.101/sql/sql_partition.cc	2007-03-06 18:54:02 +01:00
@@ -305,7 +305,7 @@
   the partition ids of the old and the new record.
 
   SYNOPSIS
-    get_part_for_update()
+    get_parts_for_update()
     old_data                Buffer of old record
     new_data                Buffer of new record
     rec0                    Reference to table->record[0]
@@ -1422,13 +1422,14 @@
                                            uint no_parts)
 {
   uint32 part_id= (uint32)(hash_value & mask);
+  DBUG_ENTER("get_part_id_from_linear_hash");
 
   if (part_id >= no_parts)
   {
     uint new_mask= ((mask + 1) >> 1) - 1;
     part_id= (uint32)(hash_value & new_mask);
   }
-  return part_id;
+  DBUG_RETURN(part_id);
 }
 
 
@@ -1679,6 +1680,7 @@
   set_up_partition_key_maps(table, part_info);
   set_up_partition_func_pointers(part_info);
   set_up_range_analysis_info(part_info);
+  table->file->set_part_info(part_info, FALSE);
   result= FALSE;
 end:
   thd->mark_used_columns= save_mark_used_columns;
@@ -2214,7 +2216,6 @@
   return value;
 }
 
-
 /*
   The next set of functions are used to calculate the partition identity.
   A handler sets up a variable that corresponds to one of these functions
@@ -2227,41 +2228,15 @@
 
   We have a set of support functions for these 14 variants. There are 4
   variants of hash functions and there is a function for each. The KEY
-  partitioning uses the function calculate_key_value to calculate the hash
-  value based on an array of fields. The linear hash variants uses the
+  partitioning uses the function calculate_key_hash_value to calculate the
+  hash value based on an array of fields. The linear hash variants uses the
   method get_part_id_from_linear_hash to get the partition id using the
   hash value and some parameters calculated from the number of partitions.
-*/
-
-/*
-  Calculate hash value for KEY partitioning using an array of fields.
-
-  SYNOPSIS
-    calculate_key_value()
-    field_array             An array of the fields in KEY partitioning
-
-  RETURN VALUE
-    hash_value calculated
 
-  DESCRIPTION
-    Uses the hash function on the character set of the field. Integer and
-    floating point fields use the binary character set by default.
+  Handlers can implement their own calculate_key_hash_value function or use the
+  method defined in ha_partition.cc
 */
 
-static uint32 calculate_key_value(Field **field_array)
-{
-  ulong nr1= 1;
-  ulong nr2= 4;
-
-  do
-  {
-    Field *field= *field_array;
-    field->hash(&nr1, &nr2);
-  } while (*(++field_array));
-  return (uint32) nr1;
-}
-
-
 /*
   A simple support function to calculate part_id given local part and
   sub part.
@@ -2344,20 +2319,23 @@
 
   SYNOPSIS
     get_part_id_key()
+    file                Handle to storage engine
     field_array         Array of fields for PARTTION KEY
     no_parts            Number of KEY partitions
+    func_value          Returns hash value calculated
 
   RETURN VALUE
     Calculated partition id
 */
 
 inline
-static uint32 get_part_id_key(Field **field_array,
+static uint32 get_part_id_key(handler *file,
+                              Field **field_array,
                               uint no_parts,
                               longlong *func_value)
 {
   DBUG_ENTER("get_part_id_key");
-  *func_value= calculate_key_value(field_array);
+  *func_value= file->calculate_key_hash_value(field_array);
   DBUG_RETURN((uint32) (*func_value % no_parts));
 }
 
@@ -2384,7 +2362,7 @@
 {
   DBUG_ENTER("get_partition_id_linear_key");
 
-  *func_value= calculate_key_value(field_array);
+  *func_value= part_info->table->file->calculate_key_hash_value(field_array);
   DBUG_RETURN(get_part_id_from_linear_hash(*func_value,
                                            part_info->linear_hash_mask,
                                            no_parts));
@@ -2553,13 +2531,14 @@
                                             longlong *func_value)
 {
   int res;
+  DBUG_ENTER("get_part_id_charset_func_subpart");
   copy_to_part_field_buffers(part_info->subpart_charset_field_array,
                              part_info->subpart_field_buffers,
                              part_info->restore_subpart_field_ptrs);
   res= part_info->get_partition_id_charset(part_info, part_id, func_value);
   restore_part_field_pointers(part_info->subpart_charset_field_array,
                               part_info->restore_subpart_field_ptrs);
-  return res;
+  DBUG_RETURN(res);
 }
 
 
@@ -2568,13 +2547,14 @@
                                          longlong *func_value)
 {
   int res;
+  DBUG_ENTER("get_part_id_charset_func_part");
   copy_to_part_field_buffers(part_info->part_charset_field_array,
                              part_info->part_field_buffers,
                              part_info->restore_part_field_ptrs);
   res= part_info->get_partition_id_charset(part_info, part_id, func_value);
   restore_part_field_pointers(part_info->part_charset_field_array,
                               part_info->restore_part_field_ptrs);
-  return res;
+  DBUG_RETURN(res);
 }
 
 
@@ -2583,13 +2563,14 @@
                                         longlong *func_value)
 {
   int res;
+  DBUG_ENTER("get_part_id_charset_func_all");
   copy_to_part_field_buffers(part_info->full_part_field_array,
                              part_info->full_part_field_buffers,
                              part_info->restore_full_part_field_ptrs);
   res= part_info->get_partition_id_charset(part_info, part_id, func_value);
   restore_part_field_pointers(part_info->full_part_field_array,
                               part_info->restore_full_part_field_ptrs);
-  return res;
+  DBUG_RETURN(res);
 }
 
 
@@ -2598,6 +2579,7 @@
                                          longlong *func_value)
 {
   int res;
+  DBUG_ENTER("get_part_part_id_charset_func");
   copy_to_part_field_buffers(part_info->part_charset_field_array,
                              part_info->part_field_buffers,
                              part_info->restore_part_field_ptrs);
@@ -2605,20 +2587,21 @@
                                                 part_id, func_value);
   restore_part_field_pointers(part_info->part_charset_field_array,
                               part_info->restore_part_field_ptrs);
-  return res;
+  DBUG_RETURN(res);
 }
 
 
 static uint32 get_subpart_id_charset_func(partition_info *part_info)
 {
   int res;
+  DBUG_ENTER("get_subpart_id_charset_func");
   copy_to_part_field_buffers(part_info->subpart_charset_field_array,
                              part_info->subpart_field_buffers,
                              part_info->restore_subpart_field_ptrs);
   res= part_info->get_subpartition_id_charset(part_info);
   restore_part_field_pointers(part_info->subpart_charset_field_array,
                               part_info->restore_subpart_field_ptrs);
-  return res;
+  DBUG_RETURN(res);
 }
 
 
@@ -2714,6 +2697,7 @@
                                                bool include_endpoint)
 {
   uint32 res;
+  DBUG_ENTER("get_list_array_idx_for_endpoint_charset");
   copy_to_part_field_buffers(part_info->part_field_array,
                              part_info->part_field_buffers,
                              part_info->restore_part_field_ptrs);
@@ -2721,7 +2705,7 @@
                                        include_endpoint);
   restore_part_field_pointers(part_info->part_field_array,
                               part_info->restore_part_field_ptrs);
-  return res;
+  DBUG_RETURN(res);
 }
 
 uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
@@ -2859,6 +2843,7 @@
                                             bool include_endpoint)
 {
   uint32 res;
+  DBUG_ENTER("get_partition_id_range_for_endpoint_charset");
   copy_to_part_field_buffers(part_info->part_field_array,
                              part_info->part_field_buffers,
                              part_info->restore_part_field_ptrs);
@@ -2866,7 +2851,7 @@
                                            include_endpoint);
   restore_part_field_pointers(part_info->part_field_array,
                               part_info->restore_part_field_ptrs);
-  return res;
+  DBUG_RETURN(res);
 }
 
 uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
@@ -2925,8 +2910,8 @@
 
 
 int get_partition_id_hash_nosub(partition_info *part_info,
-                                 uint32 *part_id,
-                                 longlong *func_value)
+                                uint32 *part_id,
+                                longlong *func_value)
 {
   *part_id= get_part_id_hash(part_info->no_parts, part_info->part_expr,
                              func_value);
@@ -2935,8 +2920,8 @@
 
 
 int get_partition_id_linear_hash_nosub(partition_info *part_info,
-                                        uint32 *part_id,
-                                        longlong *func_value)
+                                       uint32 *part_id,
+                                       longlong *func_value)
 {
   *part_id= get_part_id_linear_hash(part_info, part_info->no_parts,
                                     part_info->part_expr, func_value);
@@ -2948,7 +2933,8 @@
                                 uint32 *part_id,
                                 longlong *func_value)
 {
-  *part_id= get_part_id_key(part_info->part_field_array,
+  *part_id= get_part_id_key(part_info->table->file,
+                            part_info->part_field_array,
                             part_info->no_parts, func_value);
   return 0;
 }
@@ -3028,7 +3014,8 @@
     DBUG_RETURN(error);
   }
   no_subparts= part_info->no_subparts;
-  sub_part_id= get_part_id_key(part_info->subpart_field_array,
+  sub_part_id= get_part_id_key(part_info->table->file,
+                               part_info->subpart_field_array,
                                no_subparts, &local_func_value);
   *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
   DBUG_RETURN(0);
@@ -3122,7 +3109,8 @@
     DBUG_RETURN(error);
   }
   no_subparts= part_info->no_subparts;
-  sub_part_id= get_part_id_key(part_info->subpart_field_array,
+  sub_part_id= get_part_id_key(part_info->table->file,
+                               part_info->subpart_field_array,
                                no_subparts, &local_func_value);
   *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
   DBUG_RETURN(0);
@@ -3196,7 +3184,8 @@
 uint32 get_partition_id_key_sub(partition_info *part_info)
 {
   longlong func_value;
-  return get_part_id_key(part_info->subpart_field_array,
+  return get_part_id_key(part_info->table->file,
+                         part_info->subpart_field_array,
                          part_info->no_subparts, &func_value);
 }
 
@@ -3506,7 +3495,7 @@
   part_spec->start_part= 0;
   part_spec->end_part= no_parts - 1;
   if ((index < MAX_KEY) && 
-       key_spec->flag == (uint)HA_READ_KEY_EXACT &&
+       key_spec && key_spec->flag == (uint)HA_READ_KEY_EXACT &&
        part_info->some_fields_in_PF.is_set(index))
   {
     key_info= table->key_info+index;
@@ -3808,7 +3797,8 @@
     }
   }
   table->part_info= part_info;
-  table->file->set_part_info(part_info);
+  part_info->table= table;
+  table->file->set_part_info(part_info, TRUE);
   if (!part_info->default_engine_type)
     part_info->default_engine_type= default_db_type;
   DBUG_ASSERT(part_info->default_engine_type == default_db_type);
@@ -6691,11 +6681,12 @@
                                            uint flags,
                                            PARTITION_ITERATOR *part_iter)
 {
-  DBUG_ASSERT(!is_subpart);
   Field *field= part_info->part_field_array[0];
   uint32             max_endpoint_val;
   get_endpoint_func  get_endpoint;
   uint field_len= field->pack_length_in_rec();
+  DBUG_ENTER("get_part_iter_for_interval_via_mapping");
+  DBUG_ASSERT(!is_subpart);
 
   if (part_info->part_type == RANGE_PARTITION)
   {
@@ -6727,7 +6718,7 @@
       part_iter->part_nums.start= part_iter->part_nums.end= 0;
       part_iter->part_nums.cur= 0;
       part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE;
-      return -1;
+      DBUG_RETURN(-1);
     }
   }
   else
@@ -6746,7 +6737,7 @@
     {
       /* The right bound is X <= NULL, i.e. it is a "X IS NULL" interval */
       part_iter->part_nums.end= 0;
-      return 1;
+      DBUG_RETURN(1);
     }
   }
   else
@@ -6767,7 +6758,9 @@
       part_iter->part_nums.start= get_endpoint(part_info, 1, include_endp);
       part_iter->part_nums.cur= part_iter->part_nums.start;
       if (part_iter->part_nums.start == max_endpoint_val)
-        return 0; /* No partitions */
+      {
+        DBUG_RETURN(0); /* No partitions */
+      }
     }
   }
 
@@ -6782,9 +6775,11 @@
     part_iter->part_nums.end= get_endpoint(part_info, 0, include_endp);
     if (part_iter->part_nums.start == part_iter->part_nums.end &&
         !part_iter->ret_null_part)
-      return 0; /* No partitions */
+    {
+      DBUG_RETURN(0); /* No partitions */
+    }
   }
-  return 1; /* Ok, iterator initialized */
+  DBUG_RETURN(1); /* Ok, iterator initialized */
 }
 
 
@@ -6850,6 +6845,7 @@
   Field *field;
   uint total_parts;
   partition_iter_func get_next_func;
+  DBUG_ENTER("get_part_iter_for_interval_via_walking");
   if (is_subpart)
   {
     field= part_info->subpart_field_array[0];
@@ -6878,7 +6874,7 @@
     {
       part_id= part_info->get_subpartition_id(part_info);
       init_single_partition_iterator(part_id, part_iter);
-      return 1; /* Ok, iterator initialized */
+      DBUG_RETURN(1); /* Ok, iterator initialized */
     }
     else
     {
@@ -6890,10 +6886,10 @@
       if (!res)
       {
         init_single_partition_iterator(part_id, part_iter);
-        return 1; /* Ok, iterator initialized */
+        DBUG_RETURN(1); /* Ok, iterator initialized */
       }
     }
-    return 0; /* No partitions match */
+    DBUG_RETURN(0); /* No partitions match */
   }
 
   if ((field->real_maybe_null() && 
@@ -6901,7 +6897,7 @@
         (!(flags & NO_MAX_RANGE) && *max_value))) ||  // X <? NULL
       (flags & (NO_MIN_RANGE | NO_MAX_RANGE)))    // -inf at any bound
   {
-    return -1; /* Can't handle this interval, have to use all partitions */
+    DBUG_RETURN(-1); /* Can't handle this interval, have to use all partitions */
   }
   
   /* Get integers for left and right interval bound */
@@ -6920,20 +6916,22 @@
     an empty interval by "wrapping around" a + 4G-1 + 1 = a. 
   */
   if ((ulonglong)b - (ulonglong)a == ~0ULL)
-    return -1;
-
+  {
+    DBUG_RETURN(-1);
+  }
   a += test(flags & NEAR_MIN);
   b += test(!(flags & NEAR_MAX));
   ulonglong n_values= b - a;
   
   if (n_values > total_parts || n_values > MAX_RANGE_TO_WALK)
-    return -1;
-
+  {
+    DBUG_RETURN(-1);
+  }
   part_iter->field_vals.start= part_iter->field_vals.cur= a;
   part_iter->field_vals.end=   b;
   part_iter->part_info= part_info;
   part_iter->get_next=  get_next_func;
-  return 1;
+  DBUG_RETURN(1);
 }
 
 

--- 1.10/storage/ndb/include/mgmapi/ndb_logevent.h	2007-02-20 15:37:12 +01:00
+++ 1.11/storage/ndb/include/mgmapi/ndb_logevent.h	2007-03-06 19:36:44 +01:00
@@ -175,10 +175,8 @@
     /* 59 used */
 
     /** NDB_MGM_EVENT_CATEGORY_STARTUP */
-    NDB_LE_StartReport = 60
-
-    /* 60 used */
-    /* 61 used */
+    NDB_LE_StartReport = 60,
+    NDB_LE_ReportLockTimers = 61
     /* 62 unused */
 
   };
@@ -529,7 +527,15 @@
 	unsigned abort_count;
 	unsigned scan_count;
 	unsigned range_scan_count;
+        unsigned single_scan_count;
+        unsigned single_scan_no_distr;
+        unsigned op_no_distr;
       } TransReportCounters;
+
+      struct {
+        unsigned no_lock_timer_waits[16];
+        unsigned no_lock_waits;
+      } ReportLockTimers;
       /** Log event specific data for for corresponding NDB_LE_ log event */
       struct {
 	unsigned ops;
Thread
bk commit into 5.1 tree (mikron:1.2438)mikael6 Mar