List:Commits« Previous MessageNext Message »
From:jonas oreland Date:April 5 2011 6:47am
Subject:bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch (jonas:3469 to
3470)
View as plain text  
 3470 jonas oreland	2011-04-05 [merge]
      ndb - merge 70 into 70-spj

    added:
      storage/ndb/include/util/ndb_base64.h
    modified:
      mysql-test/include/default_ndbd.cnf
      storage/ndb/CMakeLists.txt
      storage/ndb/src/common/util/ndb_opts.c
      storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
      storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
      storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
      storage/ndb/src/mgmapi/mgmapi.cpp
      storage/ndb/src/mgmsrv/Config.cpp
      storage/ndb/src/mgmsrv/Services.cpp
      storage/ndb/test/include/HugoCalculator.hpp
      storage/ndb/test/ndbapi/testIndex.cpp
      storage/ndb/test/ndbapi/testInterpreter.cpp
      storage/ndb/test/run-test/daily-basic-tests.txt
      storage/ndb/test/src/HugoCalculator.cpp
 3469 Ole John Aske	2011-03-31
      Added or updated Copyright info for files added as part of the SPJ project.
      
      .... Recommit after resolving merge conflicts...

    modified:
      sql/ha_ndbcluster_push.cc
      sql/ha_ndbcluster_push.h
      storage/ndb/src/ndbapi/NdbQueryBuilder.cpp
      storage/ndb/src/ndbapi/NdbQueryBuilder.hpp
      storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp
      storage/ndb/src/ndbapi/NdbQueryOperation.cpp
      storage/ndb/src/ndbapi/NdbQueryOperation.hpp
      storage/ndb/src/ndbapi/NdbQueryOperationImpl.hpp
      storage/ndb/test/ndbapi/testSpj.cpp
      storage/ndb/test/tools/hugoJoin.cpp
      storage/ndb/test/tools/spj_performance_test.cpp
      storage/ndb/test/tools/spj_sanity_test.cpp
      storage/ndb/test/tools/test_spj.cpp
=== modified file 'mysql-test/include/default_ndbd.cnf'
--- a/mysql-test/include/default_ndbd.cnf	2011-02-15 11:41:27 +0000
+++ b/mysql-test/include/default_ndbd.cnf	2011-03-31 20:19:39 +0000
@@ -14,6 +14,7 @@ TimeBetweenEpochs=             100
 NoOfFragmentLogFiles=          4
 FragmentLogFileSize=           12M
 DiskPageBufferMemory=          4M
+SharedGlobalMemory=            20M
 TwoPassInitialNodeRestartCopy=1
 
 # O_DIRECT has issues on 2.4 whach have not been handled, Bug #29612

=== modified file 'storage/ndb/CMakeLists.txt'
--- a/storage/ndb/CMakeLists.txt	2011-02-04 11:45:24 +0000
+++ b/storage/ndb/CMakeLists.txt	2011-04-05 06:46:48 +0000
@@ -18,6 +18,20 @@ SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PAT
     ${CMAKE_SOURCE_DIR}/cmake
     ${CMAKE_SOURCE_DIR}/storage/ndb/cmake)
 
+# Temporarily remove -Werror from compiler flags until
+# storage/ndb/ can be built with it
+STRING(REPLACE "-Werror" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
+STRING(REPLACE "-Werror" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+
+IF (MYSQL_VERSION_ID LESS 50500)
+  # Use same compiler defines as MySQL Server for debug compile
+  MESSAGE(STATUS "Setting same debug compile defines")
+  SET(CMAKE_CXX_FLAGS_DEBUG
+      "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+  SET(CMAKE_C_FLAGS_DEBUG
+      "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+ENDIF()
+
 IF(SOURCE_SUBLIBS)
   # Sourced by libmysqld/CMakeLists.txt in 5.1 only to get
   # NDBCLUSTER_SOURCES and NDBCLUSTER_LIBS, don't configure
@@ -50,39 +64,30 @@ ELSE()
   # The root of storage/ndb/
   SET(NDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 
-ENDIF()
+  OPTION(WITH_NDB_TEST
+    "Include the NDB Cluster ndbapi test programs" OFF)
+  IF(WITH_NDB_TEST)
+    MESSAGE(STATUS "Building NDB test programs")
+  ENDIF()
 
-OPTION(WITH_NDB_TEST
-  "Include the NDB Cluster ndbapi test programs" OFF)
-IF(WITH_NDB_TEST)
-  MESSAGE(STATUS "Building NDB test programs")
-ENDIF()
+  OPTION(WITH_NDB_BINLOG
+    "Disable NDB binlog" ON)
 
-OPTION(WITH_NDB_BINLOG
-  "Disable NDB binlog" ON)
+  OPTION(WITH_ERROR_INSERT
+    "Enable error injection in MySQL Cluster" OFF)
 
-# Use same compiler defines as MySQL Server for debug compile
-SET(CMAKE_CXX_FLAGS_DEBUG
-    "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-SET(CMAKE_C_FLAGS_DEBUG
-    "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-
-OPTION(WITH_ERROR_INSERT
-  "Enable error injection in MySQL Cluster" OFF)
-
-OPTION(WITH_NDB_DEBUG
-  "Disable special ndb debug features" OFF)
-IF(WITH_NDB_DEBUG)
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -DVM_TRACE -DNDB_DEBUG -DERROR_INSERT -DARRAY_GUARD -DACC_SAFE_QUEUE")
-  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_DEBUG} -DVM_TRACE -DNDB_DEBUG -DERROR_INSERT -DARRAY_GUARD -DACC_SAFE_QUEUE")
-ELSE()
-  IF(WITH_ERROR_INSERT)
-    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DERROR_INSERT")
-    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DERROR_INSERT")
+  OPTION(WITH_NDB_DEBUG
+    "Disable special ndb debug features" OFF)
+  IF(WITH_NDB_DEBUG)
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -DVM_TRACE -DNDB_DEBUG -DERROR_INSERT -DARRAY_GUARD -DACC_SAFE_QUEUE")
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_DEBUG} -DVM_TRACE -DNDB_DEBUG -DERROR_INSERT -DARRAY_GUARD -DACC_SAFE_QUEUE")
+  ELSE()
+    IF(WITH_ERROR_INSERT)
+      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DERROR_INSERT")
+      SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DERROR_INSERT")
+    ENDIF()
   ENDIF()
-ENDIF()
 
-IF(NOT SOURCE_SUBLIBS)
   ADD_SUBDIRECTORY(include)
   ADD_SUBDIRECTORY(src)
   ADD_SUBDIRECTORY(tools)

=== added file 'storage/ndb/include/util/ndb_base64.h'
--- a/storage/ndb/include/util/ndb_base64.h	1970-01-01 00:00:00 +0000
+++ b/storage/ndb/include/util/ndb_base64.h	2011-03-28 09:01:03 +0000
@@ -0,0 +1,51 @@
+/*
+   Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+*/
+#ifndef NDB_BASE64_H
+#define NDB_BASE64_H
+
+/*
+  Interface created to be able to use base64 functions
+  using function signatures which does not change between
+  MySQL version
+*/
+
+#include <base64.h>
+#include <mysql_version.h>
+
+/*
+  Decode a base64 string into data
+*/
+static inline
+int ndb_base64_decode(const char *src, size_t src_len,
+                      void *dst, const char **end_ptr)
+{
+#ifndef MYSQL_VERSION_ID
+#error "Need MYSQL_VERSION_ID defined"
+#endif
+
+  return base64_decode(src, src_len, dst, end_ptr
+#if MYSQL_VERSION_ID >= 50603
+  // Signature of base64_decode changed to be extended
+  // with a "flags" argument in 5.6.3, no flags needed for
+  // vanilla base64_decode so ignore it in this impl.
+                       , 0);
+#else
+                       );
+#endif
+}
+
+#endif

=== modified file 'storage/ndb/src/common/util/ndb_opts.c'
--- a/storage/ndb/src/common/util/ndb_opts.c	2011-01-30 23:13:49 +0000
+++ b/storage/ndb/src/common/util/ndb_opts.c	2011-03-28 08:41:48 +0000
@@ -121,12 +121,12 @@ my_bool ndb_is_load_default_arg_separato
 #error "Need MYSQL_VERSION_ID defined"
 #endif
 
-#if MYSQL_VERSION_ID >= 50501
+#if MYSQL_VERSION_ID >= 50510
   /*
     load_default() in 5.5+ returns an extra arg which has to
     be skipped when processing the argv array
    */
-  if (arg == args_separator)
+  if (my_getopt_is_args_separator(arg))
     return TRUE;
 #else
   (void)arg;

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2011-02-24 07:39:24 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2011-04-05 06:46:48 +0000
@@ -237,8 +237,7 @@ public:
     IOS_NOOP = 0,
     IOS_INDEX_ACCESS = 1,
     IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF = 2,
-    IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI = 3,
-    IOS_INDEX_OPERATION = 4
+    IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI = 3
   };
   
   enum IndexState {
@@ -704,15 +703,20 @@ public:
     ReturnSignal returnsignal;
     AbortState abortState;
 
-    Uint8 indexOpReturn;
-    Uint8 triggerPending; // Used to mark waiting for a CONTINUEB
+    enum TransactionFlags
+    {
+      TF_INDEX_OP_RETURN = 1,
+      TF_TRIGGER_PENDING = 2, // Used to mark waiting for a CONTINUEB
+      TF_EXEC_FLAG       = 4,
+      TF_COMMIT_ACK_MARKER_RECEIVED = 8,
+      TF_END = 0
+    };
+    Uint32 m_flags;
 
-    Uint8 m_exec_flag;
     Uint8 m_special_op_flags; // Used to mark on-going TcKeyReq as indx table
 
     Uint8 takeOverRec;
     Uint8 currentReplicaNo;
-    Uint8 m_commit_ack_marker_received;
 
     Uint8 tckeyrec; // Changed from R
 
@@ -957,8 +961,6 @@ public:
     UintR packedWordsLqh[26];
     UintR noOfWordsTCKEYCONF;
     UintR packedWordsTCKEYCONF[30];
-    UintR noOfWordsTCINDXCONF;
-    UintR packedWordsTCINDXCONF[30];
     BlockReference hostLqhBlockRef;
 
     enum NodeFailBits
@@ -1406,9 +1408,6 @@ private:
   void sendPackedTCKEYCONF(Signal* signal,
                            HostRecord * ahostptr,
                            UintR hostId);
-  void sendPackedTCINDXCONF(Signal* signal,
-                            HostRecord * ahostptr,
-                            UintR hostId);
   void sendPackedSignalLqh(Signal* signal, HostRecord * ahostptr);
   Uint32 sendCommitLqh(Signal* signal,
                        TcConnectRecord * const regTcPtr);
@@ -1506,7 +1505,6 @@ private:
                      BlockReference TBRef);
   void sendSystemError(Signal* signal, int line);
   void sendtckeyconf(Signal* signal, UintR TcommitFlag);
-  void sendTcIndxConf(Signal* signal, UintR TcommitFlag);
   void unlinkApiConnect(Ptr<GcpRecord>, Ptr<ApiConnectRecord>);
   void unlinkGcp(Ptr<GcpRecord>);
   void unlinkReadyTcCon(Signal* signal);

=== modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2011-02-24 07:39:24 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2011-04-05 06:46:48 +0000
@@ -185,6 +185,22 @@ Dbtc::updateBuddyTimer(ApiConnectRecordP
   }//if
 }
 
+static
+inline
+bool
+tc_testbit(Uint32 flags, Uint32 flag)
+{
+  return (flags & flag) != 0;
+}
+
+static
+inline
+void
+tc_clearbit(Uint32 & flags, Uint32 flag)
+{
+  flags &= ~(Uint32)flag;
+}
+
 void Dbtc::execCONTINUEB(Signal* signal) 
 {
   UintR tcase;
@@ -313,8 +329,9 @@ void Dbtc::execCONTINUEB(Signal* signal)
     if (likely((transPtr.p->transid[0] == Tdata1) &&
                (transPtr.p->transid[1] == Tdata2)))
     {
-      ndbrequire(transPtr.p->triggerPending);
-      transPtr.p->triggerPending = false;
+      ndbrequire(tc_testbit(transPtr.p->m_flags,
+                            ApiConnectRecord::TF_TRIGGER_PENDING));
+      tc_clearbit(transPtr.p->m_flags, ApiConnectRecord::TF_TRIGGER_PENDING);
       /* Try executing triggers now */
       executeTriggers(signal, &transPtr);
     }
@@ -1769,7 +1786,7 @@ start_failure:
   {
     jam();
     initApiConnectRec(signal, apiConnectptr.p, true);
-    apiConnectptr.p->m_exec_flag = 1;
+    apiConnectptr.p->m_flags |= ApiConnectRecord::TF_EXEC_FLAG;
     goto start_failure;
   }
   case 61:
@@ -1904,7 +1921,6 @@ void Dbtc::execKEYINFO(Signal* signal) 
   }//switch
 }//Dbtc::execKEYINFO()
 
-
 /**
  * sendKeyInfoTrain
  * Method to send a KeyInfo signal train from KeyInfo in the supplied
@@ -2304,7 +2320,7 @@ void Dbtc::initApiConnectRec(Signal* sig
   UintR Ttransid0 = tcKeyReq->transId1;
   UintR Ttransid1 = tcKeyReq->transId2;
 
-  regApiPtr->m_exec_flag = 0;
+  tc_clearbit(regApiPtr->m_flags, ApiConnectRecord::TF_EXEC_FLAG);
   regApiPtr->returncode = 0;
   regApiPtr->returnsignal = RS_TCKEYCONF;
   ndbassert(regApiPtr->firstTcConnect == RNIL);
@@ -2315,7 +2331,8 @@ void Dbtc::initApiConnectRec(Signal* sig
   regApiPtr->lqhkeyreqrec = 0;
   regApiPtr->tckeyrec = 0;
   regApiPtr->tcindxrec = 0;
-  regApiPtr->m_commit_ack_marker_received = 0;
+  tc_clearbit(regApiPtr->m_flags,
+              ApiConnectRecord::TF_COMMIT_ACK_MARKER_RECEIVED);
   regApiPtr->no_commit_ack_markers = 0;
   regApiPtr->failureNr = TfailureNr;
   regApiPtr->transid[0] = Ttransid0;
@@ -2328,7 +2345,8 @@ void Dbtc::initApiConnectRec(Signal* sig
   // Trigger data
   releaseFiredTriggerData(&regApiPtr->theFiredTriggers);
   // Index data
-  regApiPtr->indexOpReturn = false;
+  tc_clearbit(regApiPtr->m_flags,
+              ApiConnectRecord::TF_INDEX_OP_RETURN);
   regApiPtr->noIndexOp = 0;
   if(releaseIndexOperations)
     releaseAllSeizedIndexOperations(regApiPtr);
@@ -2484,13 +2502,15 @@ void Dbtc::execTCKEYREQ(Signal* signal) 
   apiConnectptr.p = regApiPtr;
 
   Uint32 TstartFlag = TcKeyReq::getStartFlag(Treqinfo);
-  Uint32 TexecFlag = TcKeyReq::getExecuteFlag(Treqinfo);
+  Uint32 TexecFlag =
+    TcKeyReq::getExecuteFlag(Treqinfo) ? ApiConnectRecord::TF_EXEC_FLAG : 0;
 
   Uint8 Tspecial_op_flags = regApiPtr->m_special_op_flags;
-  bool isIndexOpReturn = regApiPtr->indexOpReturn;
+  bool isIndexOpReturn = tc_testbit(regApiPtr->m_flags,
+                                    ApiConnectRecord::TF_INDEX_OP_RETURN);
   bool isExecutingTrigger = Tspecial_op_flags & TcConnectRecord::SOF_TRIGGER;
   regApiPtr->m_special_op_flags = 0; // Reset marker
-  regApiPtr->m_exec_flag |= TexecFlag;
+  regApiPtr->m_flags |= TexecFlag;
   TableRecordPtr localTabptr;
   localTabptr.i = TtabIndex;
   localTabptr.p = &tableRecord[TtabIndex];
@@ -2502,7 +2522,7 @@ void Dbtc::execTCKEYREQ(Signal* signal) 
       //---------------------------------------------------------------------
       jam();
       initApiConnectRec(signal, regApiPtr);
-      regApiPtr->m_exec_flag = TexecFlag;
+      regApiPtr->m_flags |= TexecFlag;
     } else {
       releaseSections(handle);
       if(getAllowStartTransaction(sendersNodeId, localTabptr.p->singleUserMode) == true){
@@ -2541,7 +2561,7 @@ void Dbtc::execTCKEYREQ(Signal* signal) 
         return;
       }
       initApiConnectRec(signal, regApiPtr);
-      regApiPtr->m_exec_flag = TexecFlag;
+      regApiPtr->m_flags |= TexecFlag;
     } else { 
       //----------------------------------------------------------------------
       // Transaction is started already. 
@@ -2572,7 +2592,7 @@ void Dbtc::execTCKEYREQ(Signal* signal) 
 	//--------------------------------------------------------------------
         jam();
         initApiConnectRec(signal, regApiPtr);
-	regApiPtr->m_exec_flag = TexecFlag;
+	regApiPtr->m_flags |= TexecFlag;
       } else if(TexecFlag) {
         releaseSections(handle);
 	TCKEY_abort(signal, 59);
@@ -2943,7 +2963,8 @@ void Dbtc::execTCKEYREQ(Signal* signal) 
   else
   {
     /* Insert, Update, Write, Delete */
-    if (!regApiPtr->m_commit_ack_marker_received)
+    if (!tc_testbit(regApiPtr->m_flags,
+                    ApiConnectRecord::TF_COMMIT_ACK_MARKER_RECEIVED))
     {
       if(regApiPtr->commitAckMarker != RNIL)
         regTcPtr->commitAckMarker = regApiPtr->commitAckMarker;
@@ -4042,10 +4063,13 @@ void Dbtc::execSIGNAL_DROPPED_REP(Signal
     apiConnectptr.p->returncode = ZGET_DATAREC_ERROR;
 
     /* Set m_exec_flag according to the dropped request */
-    apiConnectptr.p->m_exec_flag = 
-      TcKeyReq::getExecuteFlag(truncatedTcKeyReq->requestInfo);
-
-    DEBUG("  Execute flag set to " << apiConnectptr.p->m_exec_flag);
+    apiConnectptr.p->m_flags |=
+      TcKeyReq::getExecuteFlag(truncatedTcKeyReq->requestInfo) ?
+      ApiConnectRecord::TF_EXEC_FLAG : 0;
+
+    DEBUG(" Execute flag set to " << tc_testbit(apiConnectptr.p->m_flags,
+                                                ApiConnectRecord::TF_EXEC_FLAG)
+          );
 
     abortErrorLab(signal);
 
@@ -4248,7 +4272,7 @@ void Dbtc::execLQHKEYCONF(Signal* signal
     const Uint32 noOfLqhs = regTcPtr->noOfNodes;
     CommitAckMarker * tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
     jam();
-    regApiPtr.p->m_commit_ack_marker_received = TRUE;
+    regApiPtr.p->m_flags |= ApiConnectRecord::TF_COMMIT_ACK_MARKER_RECEIVED;
     /**
      * Populate LQH array
      */
@@ -4418,7 +4442,7 @@ void Dbtc::execLQHKEYCONF(Signal* signal
 void Dbtc::setupIndexOpReturn(ApiConnectRecord* regApiPtr,
 			      TcConnectRecord* regTcPtr) 
 {
-  regApiPtr->indexOpReturn = true;
+  regApiPtr->m_flags |= ApiConnectRecord::TF_INDEX_OP_RETURN;
   regApiPtr->indexOp = regTcPtr->indexOp;
   regApiPtr->clientData = regTcPtr->clientData;
   regApiPtr->attrInfoLen = regTcPtr->attrInfoLen;
@@ -4460,7 +4484,10 @@ Dbtc::lqhKeyConf_checkTransactionState(S
         jam();
         sendtckeyconf(signal, 0);
         return;
-      } else if (regApiPtr.p->indexOpReturn) {
+      }
+      else if (tc_testbit(regApiPtr.p->m_flags,
+                          ApiConnectRecord::TF_INDEX_OP_RETURN))
+      {
 	jam();
         sendtckeyconf(signal, 0);
         return;
@@ -4483,11 +4510,14 @@ Dbtc::lqhKeyConf_checkTransactionState(S
         jam();
         sendtckeyconf(signal, 0);
         return;
-      } else if (regApiPtr.p->indexOpReturn) {
+      }
+      else if (tc_testbit(regApiPtr.p->m_flags,
+                          ApiConnectRecord::TF_INDEX_OP_RETURN))
+      {
 	jam();
         sendtckeyconf(signal, 0);
         return;
-	}//if
+      }//if
       jam();
     }//if
     return;
@@ -4497,7 +4527,10 @@ Dbtc::lqhKeyConf_checkTransactionState(S
         jam();
         sendtckeyconf(signal, 0);
         return;
-      } else if (regApiPtr.p->indexOpReturn) {
+      }
+      else if (tc_testbit(regApiPtr.p->m_flags,
+                          ApiConnectRecord::TF_INDEX_OP_RETURN))
+      {
         jam();
         sendtckeyconf(signal, 0);
         return;
@@ -4549,7 +4582,8 @@ void Dbtc::sendtckeyconf(Signal* signal,
   const UintR TpacketLen = 6 + TopWords;
   regApiPtr->tckeyrec = 0;
 
-  if (regApiPtr->indexOpReturn) {
+  if (tc_testbit(regApiPtr->m_flags, ApiConnectRecord::TF_INDEX_OP_RETURN))
+  {
     jam();
     // Return internally generated TCKEY
     TcKeyConf * const tcKeyConf = (TcKeyConf *)signal->getDataPtrSend();
@@ -4566,7 +4600,7 @@ void Dbtc::sendtckeyconf(Signal* signal,
     Uint32 sigLen = 1 /** gci_lo */ +
       TcKeyConf::StaticLength + TcKeyConf::OperationLength;
     EXECUTE_DIRECT(DBTC, GSN_TCKEYCONF, signal, sigLen);
-    regApiPtr->indexOpReturn = false;
+    tc_clearbit(regApiPtr->m_flags, ApiConnectRecord::TF_INDEX_OP_RETURN);
     if (TopWords == 0) {
       jam();
       return; // No queued TcKeyConf
@@ -4574,7 +4608,7 @@ void Dbtc::sendtckeyconf(Signal* signal,
   }//if
   if(TcommitFlag){
     jam();
-    regApiPtr->m_exec_flag = 0;
+    tc_clearbit(regApiPtr->m_flags, ApiConnectRecord::TF_EXEC_FLAG);
   }
   TcKeyConf::setNoOfOperations(confInfo, (TopWords >> 1));
   if ((TpacketLen + 1 /** gci_lo */ > 25) || !is_api){
@@ -4674,7 +4708,6 @@ void Dbtc::execSEND_PACKED(Signal* signa
     arrGuard(Thostptr.i - 1, MAX_NODES - 1);
     UintR TnoOfPackedWordsLqh = Thostptr.p->noOfPackedWordsLqh;
     UintR TnoOfWordsTCKEYCONF = Thostptr.p->noOfWordsTCKEYCONF;
-    UintR TnoOfWordsTCINDXCONF = Thostptr.p->noOfWordsTCINDXCONF;
     jam();
     if (TnoOfPackedWordsLqh > 0) {
       jam();
@@ -4684,10 +4717,6 @@ void Dbtc::execSEND_PACKED(Signal* signa
       jam();
       sendPackedTCKEYCONF(signal, Thostptr.p, (Uint32)Thostptr.i);
     }//if
-    if (TnoOfWordsTCINDXCONF > 0) {
-      jam();
-      sendPackedTCINDXCONF(signal, Thostptr.p, (Uint32)Thostptr.i);
-    }//if
     Thostptr.p->inPackedList = false;
   }//for
   cpackedListIndex = 0;
@@ -4749,27 +4778,6 @@ void Dbtc::sendPackedTCKEYCONF(Signal* s
   sendSignal(TBref, GSN_TCKEYCONF, signal, TnoOfWords, JBB);
 }//Dbtc::sendPackedTCKEYCONF()
 
-void Dbtc::sendPackedTCINDXCONF(Signal* signal,
-                                HostRecord * ahostptr,
-                                UintR hostId)
-{
-  UintR Tj;
-  UintR TnoOfWords = ahostptr->noOfWordsTCINDXCONF;
-  BlockReference TBref = numberToRef(API_PACKED, hostId);
-  for (Tj = 0; Tj < ahostptr->noOfWordsTCINDXCONF; Tj += 4) {
-    UintR sig0 = ahostptr->packedWordsTCINDXCONF[Tj + 0];
-    UintR sig1 = ahostptr->packedWordsTCINDXCONF[Tj + 1];
-    UintR sig2 = ahostptr->packedWordsTCINDXCONF[Tj + 2];
-    UintR sig3 = ahostptr->packedWordsTCINDXCONF[Tj + 3];
-    signal->theData[Tj + 0] = sig0;
-    signal->theData[Tj + 1] = sig1;
-    signal->theData[Tj + 2] = sig2;
-    signal->theData[Tj + 3] = sig3;
-  }//for
-  ahostptr->noOfWordsTCINDXCONF = 0;
-  sendSignal(TBref, GSN_TCINDXCONF, signal, TnoOfWords, JBB);
-}//Dbtc::sendPackedTCINDXCONF()
-
 /*
 4.3.11 DIVERIFY 
 ---------------
@@ -4846,7 +4854,8 @@ void Dbtc::seizeApiConnectCopy(Signal* s
   cfirstfreeApiConnectCopy = locApiConnectptr.p->nextApiConnect;
   locApiConnectptr.p->nextApiConnect = RNIL;
   regApiPtr->apiCopyRecord = locApiConnectptr.i;
-  regApiPtr->triggerPending = false;
+  tc_clearbit(regApiPtr->m_flags,
+              ApiConnectRecord::TF_TRIGGER_PENDING);
   regApiPtr->m_special_op_flags = 0;
 }//Dbtc::seizeApiConnectCopy()
 
@@ -6031,7 +6040,10 @@ void Dbtc::execLQHKEYREF(Signal* signal)
           jam();
           diverify010Lab(signal);
 	  return;
-	} else if (regApiPtr->tckeyrec > 0 || regApiPtr->m_exec_flag) {
+	}
+        else if (regApiPtr->tckeyrec > 0 ||
+                 tc_testbit(regApiPtr->m_flags, ApiConnectRecord::TF_EXEC_FLAG))
+        {
 	  jam();
 	  sendtckeyconf(signal, 2);
 	  return;
@@ -6067,7 +6079,8 @@ void Dbtc::clearCommitAckMarker(ApiConne
     if (regApiPtr->no_commit_ack_markers == 0)
     {
       regApiPtr->commitAckMarker = RNIL;
-      regApiPtr->m_commit_ack_marker_received = FALSE;
+      tc_clearbit(regApiPtr->m_flags,
+                  ApiConnectRecord::TF_COMMIT_ACK_MARKER_RECEIVED);
       m_commitAckMarkerHash.release(commitAckMarker);
     }
   }
@@ -6115,7 +6128,7 @@ void Dbtc::execTC_COMMITREQ(Signal* sign
     const Uint32 transId2      = regApiPtr->transid[1];
     Uint32 errorCode           = 0;
 
-    regApiPtr->m_exec_flag = 1;
+    regApiPtr->m_flags |= ApiConnectRecord::TF_EXEC_FLAG;
     switch (regApiPtr->apiConnectstate) {
     case CS_STARTED:
       tcConnectptr.i = regApiPtr->firstTcConnect;
@@ -6267,7 +6280,7 @@ void Dbtc::execTCROLLBACKREQ(Signal* sig
     return;
   }//if
 
-  apiConnectptr.p->m_exec_flag = 1;
+  apiConnectptr.p->m_flags |= ApiConnectRecord::TF_EXEC_FLAG;
   switch (apiConnectptr.p->apiConnectstate) {
   case CS_STARTED:
   case CS_RECEIVING:
@@ -7121,7 +7134,8 @@ void Dbtc::timeOutFoundLab(Signal* signa
 	<< " H'" << apiConnectptr.p->transid[1] << "] " << dec 
 	<< "Time-out in state = " << apiConnectptr.p->apiConnectstate
 	<< " apiConnectptr.i = " << apiConnectptr.i 
-	<< " - exec: " << apiConnectptr.p->m_exec_flag
+	<< " - exec: "
+        << tc_testbit(apiConnectptr.p->m_flags, ApiConnectRecord::TF_EXEC_FLAG)
 	<< " - place: " << c_apiConTimer_line[apiConnectptr.i]
 	<< " code: " << errCode);
   switch (apiConnectptr.p->apiConnectstate) {
@@ -11759,7 +11773,7 @@ void Dbtc::initApiConnect(Signal* signal
     apiConnectptr.p->commitAckMarker = RNIL;
     apiConnectptr.p->firstTcConnect = RNIL;
     apiConnectptr.p->lastTcConnect = RNIL;
-    apiConnectptr.p->triggerPending = false;
+    apiConnectptr.p->m_flags = 0;
     apiConnectptr.p->m_special_op_flags = 0;
     apiConnectptr.p->accumulatingIndexOp = RNIL;
     apiConnectptr.p->executingIndexOp = RNIL;
@@ -11788,7 +11802,7 @@ void Dbtc::initApiConnect(Signal* signal
       apiConnectptr.p->commitAckMarker = RNIL;
       apiConnectptr.p->firstTcConnect = RNIL;
       apiConnectptr.p->lastTcConnect = RNIL;
-      apiConnectptr.p->triggerPending = false;
+      apiConnectptr.p->m_flags = 0;
       apiConnectptr.p->m_special_op_flags = 0;
       apiConnectptr.p->accumulatingIndexOp = RNIL;
       apiConnectptr.p->executingIndexOp = RNIL;
@@ -11817,7 +11831,7 @@ void Dbtc::initApiConnect(Signal* signal
     apiConnectptr.p->commitAckMarker = RNIL;
     apiConnectptr.p->firstTcConnect = RNIL;
     apiConnectptr.p->lastTcConnect = RNIL;
-    apiConnectptr.p->triggerPending = false;
+    apiConnectptr.p->m_flags = 0;
     apiConnectptr.p->m_special_op_flags = 0;
     apiConnectptr.p->accumulatingIndexOp = RNIL;
     apiConnectptr.p->executingIndexOp = RNIL;
@@ -11859,7 +11873,6 @@ void Dbtc::inithost(Signal* signal) 
     hostptr.p->inPackedList = false;
     hostptr.p->lqhTransStatus = LTS_IDLE;
     hostptr.p->noOfWordsTCKEYCONF = 0;
-    hostptr.p->noOfWordsTCINDXCONF = 0;
     hostptr.p->noOfPackedWordsLqh = 0;
     hostptr.p->hostLqhBlockRef = calcLqhBlockRef(hostptr.i);
     hostptr.p->m_nf_bits = 0;
@@ -12124,13 +12137,15 @@ void Dbtc::releaseAbortResources(Signal*
   apiConnectptr.p->abortState = AS_IDLE;
   releaseAllSeizedIndexOperations(apiConnectptr.p);
 
-  if(apiConnectptr.p->m_exec_flag || apiConnectptr.p->apiFailState == ZTRUE){
+  if (tc_testbit(apiConnectptr.p->m_flags, ApiConnectRecord::TF_EXEC_FLAG) ||
+      apiConnectptr.p->apiFailState == ZTRUE)
+  {
     jam();
     bool ok = false;
     Uint32 blockRef = apiConnectptr.p->ndbapiBlockref;
     ReturnSignal ret = apiConnectptr.p->returnsignal;
     apiConnectptr.p->returnsignal = RS_NO_RETURN;
-    apiConnectptr.p->m_exec_flag = 0;
+    tc_clearbit(apiConnectptr.p->m_flags, ApiConnectRecord::TF_EXEC_FLAG);
     switch(ret){
     case RS_TCROLLBACKCONF:
       jam();
@@ -12232,7 +12247,8 @@ void Dbtc::seizeApiConnect(Signal* signa
     apiConnectptr.p->nextApiConnect = RNIL;
     setApiConTimer(apiConnectptr.i, 0, __LINE__);
     apiConnectptr.p->apiConnectstate = CS_CONNECTED; /* STATE OF CONNECTION */
-    apiConnectptr.p->triggerPending = false;
+    tc_clearbit(apiConnectptr.p->m_flags,
+                ApiConnectRecord::TF_TRIGGER_PENDING);
     apiConnectptr.p->m_special_op_flags = 0;
   } else {
     jam();
@@ -13650,7 +13666,9 @@ void Dbtc::execTCINDXREQ(Signal* signal)
     jam();
     releaseSections(handle);
     terrorCode = ZCLUSTER_IN_SINGLEUSER_MODE;
-    regApiPtr->m_exec_flag |= TcKeyReq::getExecuteFlag(tcIndxRequestInfo);
+    regApiPtr->m_flags |=
+      TcKeyReq::getExecuteFlag(tcIndxRequestInfo) ?
+      ApiConnectRecord::TF_EXEC_FLAG : 0;
     apiConnectptr = transPtr;
     abortErrorLab(signal);
     return;
@@ -13661,7 +13679,9 @@ void Dbtc::execTCINDXREQ(Signal* signal)
     releaseSections(handle);
     // Failed to allocate index operation
     terrorCode = 288;
-    regApiPtr->m_exec_flag |= TcKeyReq::getExecuteFlag(tcIndxRequestInfo);
+    regApiPtr->m_flags |=
+      TcKeyReq::getExecuteFlag(tcIndxRequestInfo) ?
+      ApiConnectRecord::TF_EXEC_FLAG : 0;
     apiConnectptr = transPtr;
     abortErrorLab(signal);
     return;
@@ -13752,94 +13772,6 @@ void Dbtc::execTCINDXREQ(Signal* signal)
   }
 }
 
-
-void Dbtc::sendTcIndxConf(Signal* signal, UintR TcommitFlag) 
-{
-  HostRecordPtr localHostptr;
-  ApiConnectRecord * const regApiPtr = apiConnectptr.p;
-  const UintR TopWords = (UintR)regApiPtr->tcindxrec;
-  localHostptr.i = refToNode(regApiPtr->ndbapiBlockref);
-  const Uint32 type = getNodeInfo(localHostptr.i).m_type;
-  const bool is_api = (type >= NodeInfo::API && type <= NodeInfo::MGM);
-  const BlockNumber TblockNum = refToBlock(regApiPtr->ndbapiBlockref);
-  const Uint32 Tmarker = (regApiPtr->commitAckMarker == RNIL ? 0 : 1);
-  ptrAss(localHostptr, hostRecord);
-  UintR TcurrLen = localHostptr.p->noOfWordsTCINDXCONF;
-  UintR confInfo = 0;
-  TcIndxConf::setNoOfOperations(confInfo, (TopWords >> 1));
-  TcIndxConf::setCommitFlag(confInfo, TcommitFlag == 1);
-  TcIndxConf::setMarkerFlag(confInfo, Tmarker);
-  const UintR TpacketLen = 6 + TopWords;
-  regApiPtr->tcindxrec = 0;
-
-  if(TcommitFlag || (regApiPtr->lqhkeyreqrec == regApiPtr->lqhkeyconfrec)){
-    jam();
-    regApiPtr->m_exec_flag = 0;
-  }
-
-  if ((TpacketLen + 1 /** gci_lo */ > 25) || !is_api){
-    TcIndxConf * const tcIndxConf = (TcIndxConf *)signal->getDataPtrSend();
-    
-    jam();
-    tcIndxConf->apiConnectPtr = regApiPtr->ndbapiConnect;
-    tcIndxConf->gci_hi = Uint32(regApiPtr->globalcheckpointid >> 32);
-    Uint32 *gci_lo = (Uint32*)&tcIndxConf->operations[TopWords >> 1];
-    * gci_lo = Uint32(regApiPtr->globalcheckpointid);
-    tcIndxConf->confInfo = confInfo;
-    tcIndxConf->transId1 = regApiPtr->transid[0];
-    tcIndxConf->transId2 = regApiPtr->transid[1];
-    copyFromToLen(&regApiPtr->tcIndxSendArray[0],
-                  (UintR*)&tcIndxConf->operations,
-                  (UintR)ZTCOPCONF_SIZE);
-    sendSignal(regApiPtr->ndbapiBlockref,
-               GSN_TCINDXCONF, signal,
-               (TpacketLen - 1) + 1 /** gci_lo */, JBB);
-    return;
-  } else if (((TcurrLen + TpacketLen + 1 /** gci_lo */) > 25) &&
-             (TcurrLen > 0)) {
-    jam();
-    sendPackedTCINDXCONF(signal, localHostptr.p, localHostptr.i);
-    TcurrLen = 0;
-  } else {
-    jam();
-    updatePackedList(signal, localHostptr.p, localHostptr.i);
-  }//if
-// -------------------------------------------------------------------------
-// The header contains the block reference of receiver plus the real signal
-// length - 3, since we have the real signal length plus one additional word
-// for the header we have to do - 4.
-// -------------------------------------------------------------------------
-  UintR Tpack0 = (TblockNum << 16) + (TpacketLen - 4 + 1 /** gci_lo */);
-  UintR Tpack1 = regApiPtr->ndbapiConnect;
-  UintR Tpack2 = Uint32(regApiPtr->globalcheckpointid >> 32);
-  UintR Tpack3 = confInfo;
-  UintR Tpack4 = regApiPtr->transid[0];
-  UintR Tpack5 = regApiPtr->transid[1];
-  UintR Tpack6 = Uint32(regApiPtr->globalcheckpointid);
-
-  localHostptr.p->noOfWordsTCINDXCONF = TcurrLen + TpacketLen + 1 /* gci_lo */;
-
-  localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 0] = Tpack0;
-  localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 1] = Tpack1;
-  localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 2] = Tpack2;
-  localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 3] = Tpack3;
-  localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 4] = Tpack4;
-  localHostptr.p->packedWordsTCINDXCONF[TcurrLen + 5] = Tpack5;
-
-  UintR Ti;
-  for (Ti = 6; Ti < TpacketLen; Ti++) {
-    localHostptr.p->packedWordsTCINDXCONF[TcurrLen + Ti] = 
-          regApiPtr->tcIndxSendArray[Ti - 6];
-  }//for
-  localHostptr.p->packedWordsTCINDXCONF[TcurrLen + TpacketLen] = Tpack6;
-
-  if (unlikely(!ndb_check_micro_gcp(getNodeInfo(localHostptr.i).m_version)))
-  {
-    jam();
-    ndbassert(Tpack6 == 0 || getNodeInfo(localHostptr.i).m_version == 0);
-  }
-}//Dbtc::sendTcIndxConf()
-
 void Dbtc::execINDXKEYINFO(Signal* signal)
 {
   jamEntry();
@@ -13964,7 +13896,7 @@ Dbtc::saveINDXKEYINFO(Signal* signal,
     releaseIndexOperation(apiConnectptr.p, indexOp);
     terrorCode = 289;
     if(TcKeyReq::getExecuteFlag(indexOp->tcIndxReq.requestInfo))
-      apiConnectptr.p->m_exec_flag= 1;
+      apiConnectptr.p->m_flags |= ApiConnectRecord::TF_EXEC_FLAG;
     abortErrorLab(signal);
     return -1;
   }
@@ -14006,7 +13938,7 @@ Dbtc::saveINDXATTRINFO(Signal* signal,
     releaseIndexOperation(apiConnectptr.p, indexOp);
     terrorCode = 289;
     if(TcKeyReq::getExecuteFlag(indexOp->tcIndxReq.requestInfo))
-      apiConnectptr.p->m_exec_flag= 1;
+      apiConnectptr.p->m_flags |= ApiConnectRecord::TF_EXEC_FLAG;
     abortErrorLab(signal);
     return -1;
   }
@@ -14193,7 +14125,7 @@ void Dbtc::execTCKEYCONF(Signal* signal)
   /**
    * Check on TCKEYCONF whether the the transaction was committed
    */
-  Uint32 Tcommit = TcKeyConf::getCommitFlag(confInfo);
+  ndbassert(TcKeyConf::getCommitFlag(confInfo) == false);
 
   indexOpPtr.p = indexOp;
   if (!indexOp) {
@@ -14246,28 +14178,6 @@ void Dbtc::execTCKEYCONF(Signal* signal)
     executeIndexOperation(signal, regApiPtr, indexOp);
     break;
   }
-  case(IOS_INDEX_OPERATION): {
-    // We are done, send TCINDXCONF
-    jam();    
-    Uint32 Ttcindxrec = regApiPtr->tcindxrec;
-    // Copy reply from TcKeyConf
-
-    ndbassert(regApiPtr->noIndexOp);
-    regApiPtr->noIndexOp--; // Decrease count
-    regApiPtr->tcIndxSendArray[Ttcindxrec] = indexOp->tcIndxReq.senderData;
-    regApiPtr->tcIndxSendArray[Ttcindxrec + 1] = 
-      tcKeyConf->operations[0].attrInfoLen;
-    regApiPtr->tcindxrec = Ttcindxrec + 2;
-    if (regApiPtr->noIndexOp == 0) {
-      jam();
-      sendTcIndxConf(signal, Tcommit);
-    } else if (regApiPtr->tcindxrec == ZTCOPCONF_SIZE) {
-      jam();
-      sendTcIndxConf(signal, 0);
-    }
-    releaseIndexOperation(regApiPtr, indexOp);
-    break;
-  }
   }
 }
 
@@ -14298,23 +14208,11 @@ void Dbtc::execTCKEYREF(Signal* signal)
   case(IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI):
   case(IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF): {
     jam();    
-    /**
-     * Increase count as it will be decreased below...
-     *   (and the code is written to handle failing lookup on "real" table
-     *    not lookup on index table)
-     */
-    regApiPtr->noIndexOp++;
-    // else continue
-  }
-  case(IOS_INDEX_OPERATION): {
     // Send TCINDXREF 
     
-    jam();
     TcKeyReq * const tcIndxReq = &indexOp->tcIndxReq;
     TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
     
-    ndbassert(regApiPtr->noIndexOp);
-    regApiPtr->noIndexOp--; // Decrease count
     tcIndxRef->connectPtr = tcIndxReq->senderData;
     tcIndxRef->transId[0] = tcKeyRef->transId[0];
     tcIndxRef->transId[1] = tcKeyRef->transId[1];
@@ -14510,20 +14408,6 @@ void Dbtc::execTRANSID_AI(Signal* signal
     // else continue waiting for more TRANSID_AI
     break;
   }
-  case(IOS_INDEX_OPERATION): {
-    // Should never receive TRANSID_AI in this state!!
-    jam();    
-    TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend();
-
-    tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData;
-    tcIndxRef->transId[0] = regApiPtr->transid[0];
-    tcIndxRef->transId[1] = regApiPtr->transid[1];
-    tcIndxRef->errorCode = 4349;
-    tcIndxRef->errorData = regApiPtr->errorData;
-    sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, 
-	       TcKeyRef::SignalLength, JBB);
-    return;
-  }
   }
 }
 
@@ -14581,6 +14465,7 @@ void Dbtc::readIndexTable(Signal* signal
   TcKeyReq::setOperationType(tcKeyRequestInfo, 
 			     opType == ZREAD ? ZREAD : ZREAD_EX);
   TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 0); // No AI in long TCKEYREQ
+  TcKeyReq::setInterpretedFlag(tcKeyRequestInfo, 0);
   tcKeyReq->senderData = indexOp->indexOpId;
   indexOp->indexOpState = IOS_INDEX_ACCESS;
   regApiPtr->executingIndexOp = regApiPtr->accumulatingIndexOp;
@@ -14719,10 +14604,8 @@ void Dbtc::executeIndexOperation(Signal*
     tcKeyReq->scanInfo = indexOp->fragmentId; // As read from Index table
     TcKeyReq::setDistributionKeyFlag(tcKeyRequestInfo, 1U);
   }
-  indexOp->indexOpState = IOS_INDEX_OPERATION;
-  regApiPtr->m_special_op_flags = TcConnectRecord::SOF_INDEX_BASE_TABLE_ACCESS;
-  regApiPtr->executingIndexOp = indexOp->indexOpId;;
-  regApiPtr->noIndexOp++; // Increase count
+  regApiPtr->m_special_op_flags = 0;
+  regApiPtr->executingIndexOp = 0;
 
   /* KeyInfo section
    * Get the KeyInfo we received from the index table lookup
@@ -14753,6 +14636,9 @@ void Dbtc::executeIndexOperation(Signal*
     signal->header.m_noOfSections = 2;
     indexOp->attrInfoSectionIVal = RNIL;
   }
+
+  releaseIndexOperation(regApiPtr, indexOp);
+
   TcKeyReq::setKeyLength(tcKeyRequestInfo, keyInfoFromTransIdAI.sz);
   TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 0);
   TcKeyReq::setCommitFlag(tcKeyRequestInfo, 0);
@@ -14780,12 +14666,27 @@ void Dbtc::executeIndexOperation(Signal*
   const Uint32 currSavePointId = regApiPtr->currSavePointId;
   regApiPtr->currSavePointId = tmp.p->savePointId;
 
+#ifdef ERROR_INSERT
+  bool err8072 = ERROR_INSERTED(8072);
+  if (err8072)
+  {
+    CLEAR_ERROR_INSERT_VALUE;
+  }
+#endif
+
   /* Execute TCKEYREQ now - it is now responsible for freeing
    * the KeyInfo and AttrInfo sections 
    */
   EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, TcKeyReq::StaticLength);
   jamEntry();
-  
+
+#ifdef ERROR_INSERT
+  if (err8072)
+  {
+    SET_ERROR_INSERT_VALUE(8072);
+  }
+#endif
+
   if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
   {
     // TODO : Presumably the abort cleans up the operation
@@ -14944,9 +14845,11 @@ void Dbtc::executeTriggers(Signal* signa
       {
         // Wait until transaction is ready to execute a trigger
         jam();
-        if (!regApiPtr->triggerPending) {
+        if (!tc_testbit(regApiPtr->m_flags,
+                        ApiConnectRecord::TF_TRIGGER_PENDING))
+        {
           jam();
-          regApiPtr->triggerPending = true;
+          regApiPtr->m_flags |= ApiConnectRecord::TF_TRIGGER_PENDING;
           signal->theData[0] = TcContinueB::TRIGGER_PENDING;
           signal->theData[1] = transPtr->i;
           signal->theData[2] = regApiPtr->transid[0];

=== modified file 'storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2011-03-29 19:12:09 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2011-04-05 06:46:48 +0000
@@ -1927,6 +1927,7 @@ int Dbtup::handleDeleteReq(Signal* signa
   {
     regOperPtr->tupVersion= req_struct->m_tuple_ptr->get_tuple_version();
   }
+  req_struct->changeMask.set();
 
   if(disk && regOperPtr->m_undo_buffer_space == 0)
   {

=== modified file 'storage/ndb/src/mgmapi/mgmapi.cpp'
--- a/storage/ndb/src/mgmapi/mgmapi.cpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/mgmapi/mgmapi.cpp	2011-03-28 09:01:03 +0000
@@ -35,7 +35,7 @@
 #include <OutputStream.hpp>
 #include <InputStream.hpp>
 
-#include <base64.h>
+#include <ndb_base64.h>
 
 //#define MGMAPI_LOG
 #define MGM_CMD(name, fun, desc) \
@@ -2549,7 +2549,7 @@ ndb_mgm_get_configuration2(NdbMgmHandle 
       break;
 
     void *tmp_data = malloc(base64_needed_decoded_length((size_t) (len - 1)));
-    const int res = base64_decode(buf64, len-1, tmp_data, NULL);
+    const int res = ndb_base64_decode(buf64, len-1, tmp_data, NULL);
     delete[] buf64;
     UtilBuffer tmp;
     tmp.append((void *) tmp_data, res);

=== modified file 'storage/ndb/src/mgmsrv/Config.cpp'
--- a/storage/ndb/src/mgmsrv/Config.cpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/mgmsrv/Config.cpp	2011-03-28 09:01:03 +0000
@@ -232,7 +232,7 @@ Config::pack(UtilBuffer& buf) const
 }
 
 
-#include <base64.h>
+#include <ndb_base64.h>
 
 bool
 Config::pack64(BaseString& encoded) const

=== modified file 'storage/ndb/src/mgmsrv/Services.cpp'
--- a/storage/ndb/src/mgmsrv/Services.cpp	2011-02-01 23:27:25 +0000
+++ b/storage/ndb/src/mgmsrv/Services.cpp	2011-03-28 09:01:03 +0000
@@ -34,7 +34,7 @@
 
 #include "ndb_mgmd_error.h"
 
-#include <base64.h>
+#include <ndb_base64.h>
 #include <ndberror.h>
 
 extern bool g_StopServer;
@@ -2098,7 +2098,7 @@ void MgmApiSession::setConfig(Parser_t::
     } while(start < len64);
 
     char* decoded = new char[base64_needed_decoded_length((size_t)len64 - 1)];
-    int decoded_len= base64_decode(buf64, len64-1, decoded, NULL);
+    int decoded_len= ndb_base64_decode(buf64, len64-1, decoded, NULL);
     delete[] buf64;
 
     ConfigValuesFactory cvf;

=== modified file 'storage/ndb/test/include/HugoCalculator.hpp'
--- a/storage/ndb/test/include/HugoCalculator.hpp	2011-02-04 11:45:24 +0000
+++ b/storage/ndb/test/include/HugoCalculator.hpp	2011-04-05 06:46:48 +0000
@@ -45,6 +45,9 @@ public:
   int isUpdateCol(int colId){ return m_updatesCol == colId; };
 
   const NdbDictionary::Table& getTable() const { return m_tab;}
+
+  int equalForRow(Uint8 *, const NdbRecord*, int rowid);
+  int setValues(Uint8*, const NdbRecord*, int rowid, int updateval);
 private:
   const NdbDictionary::Table& m_tab;
   int m_idCol;

=== modified file 'storage/ndb/test/ndbapi/testIndex.cpp'
--- a/storage/ndb/test/ndbapi/testIndex.cpp	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/test/ndbapi/testIndex.cpp	2011-04-01 07:10:05 +0000
@@ -2719,6 +2719,68 @@ runBug56829(NDBT_Context* ctx, NDBT_Step
   return result;
 }
 
+#define CHK_RET_FAILED(x) if (!(x)) { ndbout_c("Failed on line: %u", __LINE__); return NDBT_FAILED; }
+
+int
+runBug12315582(NDBT_Context* ctx, NDBT_Step* step)
+{
+  const NdbDictionary::Table * pTab = ctx->getTab();
+  Ndb* pNdb = GETNDB(step);
+  NdbDictionary::Dictionary * dict = pNdb->getDictionary();
+
+  const NdbDictionary::Index* pIdx= dict->getIndex(pkIdxName, pTab->getName());
+  CHK_RET_FAILED(pIdx != 0);
+
+  const NdbRecord * pRowRecord = pTab->getDefaultRecord();
+  CHK_RET_FAILED(pRowRecord != 0);
+  const NdbRecord * pIdxRecord = pIdx->getDefaultRecord();
+  CHK_RET_FAILED(pIdxRecord != 0);
+
+  const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
+  Uint8 * pRow = new Uint8[len];
+  bzero(pRow, len);
+
+  HugoCalculator calc(* pTab);
+  calc.equalForRow(pRow, pRowRecord, 0);
+
+  NdbTransaction* pTrans = pNdb->startTransaction();
+  CHK_RET_FAILED(pTrans != 0);
+
+  const NdbOperation * pOp[2] = { 0, 0 };
+  for (Uint32 i = 0; i<2; i++)
+  {
+    NdbInterpretedCode code;
+    if (i == 0)
+      code.interpret_exit_ok();
+    else
+      code.interpret_exit_nok();
+
+    code.finalise();
+
+    NdbOperation::OperationOptions opts;
+    bzero(&opts, sizeof(opts));
+    opts.optionsPresent = NdbOperation::OperationOptions::OO_INTERPRETED;
+    opts.interpretedCode = &code;
+
+    pOp[i] = pTrans->readTuple(pIdxRecord, (char*)pRow,
+                               pRowRecord, (char*)pRow,
+                               NdbOperation::LM_Read,
+                               0,
+                               &opts,
+                               sizeof(opts));
+    CHK_RET_FAILED(pOp[i]);
+  }
+
+  int res = pTrans->execute(Commit, AO_IgnoreError);
+
+  CHK_RET_FAILED(res == 0);
+  CHK_RET_FAILED(pOp[0]->getNdbError().code == 0);
+  CHK_RET_FAILED(pOp[1]->getNdbError().code != 0);
+
+  delete [] pRow;
+
+  return NDBT_OK;
+}
 
 NDBT_TESTSUITE(testIndex);
 TESTCASE("CreateAll", 
@@ -3125,7 +3187,15 @@ TESTCASE("Bug56829",
          "so that empty fragment pages can be freed"){
   STEP(runBug56829);
 }
-  
+TESTCASE("Bug12315582", "")
+{
+  TC_PROPERTY("LoggedIndexes", Uint32(0));
+  TC_PROPERTY("OrderedIndex", Uint32(0));
+  INITIALIZER(createPkIndex);
+  INITIALIZER(runLoadTable);
+  INITIALIZER(runBug12315582);
+  FINALIZER(createPkIndex_Drop);
+}
 NDBT_TESTSUITE_END(testIndex);
 
 int main(int argc, const char** argv){

=== modified file 'storage/ndb/test/ndbapi/testInterpreter.cpp'
--- a/storage/ndb/test/ndbapi/testInterpreter.cpp	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/test/ndbapi/testInterpreter.cpp	2011-03-31 12:43:59 +0000
@@ -389,6 +389,148 @@ int runTestBug34107(NDBT_Context* ctx, N
   return NDBT_OK;
 }
 
+static char pkIdxName[256];
+
+int
+createPkIndex(NDBT_Context* ctx, NDBT_Step* step){
+  const NdbDictionary::Table* pTab = ctx->getTab();
+  Ndb* pNdb = GETNDB(step);
+
+  bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
+  bool logged = ctx->getProperty("LoggedIndexes", (Uint32)0);
+  bool noddl= ctx->getProperty("NoDDL");
+
+  // Create index
+  BaseString::snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName());
+  if (orderedIndex)
+    ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "
+	   << pkIdxName << " (";
+  else
+    ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "
+	   << pkIdxName << " (";
+
+  NdbDictionary::Index pIdx(pkIdxName);
+  pIdx.setTable(pTab->getName());
+  if (orderedIndex)
+    pIdx.setType(NdbDictionary::Index::OrderedIndex);
+  else
+    pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
+  for (int c = 0; c< pTab->getNoOfColumns(); c++){
+    const NdbDictionary::Column * col = pTab->getColumn(c);
+    if(col->getPrimaryKey()){
+      pIdx.addIndexColumn(col->getName());
+      ndbout << col->getName() <<" ";
+    }
+  }
+
+  pIdx.setStoredIndex(logged);
+  ndbout << ") ";
+  if (noddl)
+  {
+    const NdbDictionary::Index* idx= pNdb->
+      getDictionary()->getIndex(pkIdxName, pTab->getName());
+
+    if (!idx)
+    {
+      ndbout << "Failed - Index does not exist and DDL not allowed" << endl;
+      ERR(pNdb->getDictionary()->getNdbError());
+      return NDBT_FAILED;
+    }
+    else
+    {
+      // TODO : Check index definition is ok
+    }
+  }
+  else
+  {
+    if (pNdb->getDictionary()->createIndex(pIdx) != 0){
+      ndbout << "FAILED!" << endl;
+      const NdbError err = pNdb->getDictionary()->getNdbError();
+      ERR(err);
+      return NDBT_FAILED;
+    }
+  }
+
+  ndbout << "OK!" << endl;
+  return NDBT_OK;
+}
+
+int
+createPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step)
+{
+  const NdbDictionary::Table* pTab = ctx->getTab();
+  Ndb* pNdb = GETNDB(step);
+
+  bool noddl= ctx->getProperty("NoDDL");
+
+  // Drop index
+  if (!noddl)
+  {
+    ndbout << "Dropping index " << pkIdxName << " ";
+    if (pNdb->getDictionary()->dropIndex(pkIdxName,
+                                         pTab->getName()) != 0){
+      ndbout << "FAILED!" << endl;
+      ERR(pNdb->getDictionary()->getNdbError());
+      return NDBT_FAILED;
+    } else {
+      ndbout << "OK!" << endl;
+    }
+  }
+
+  return NDBT_OK;
+}
+
+#define CHK_RET_FAILED(x) if (!(x)) { ndbout_c("Failed on line: %u", __LINE__); return NDBT_FAILED; }
+
+int
+runInterpretedUKLookup(NDBT_Context* ctx, NDBT_Step* step)
+{
+  const NdbDictionary::Table * pTab = ctx->getTab();
+  Ndb* pNdb = GETNDB(step);
+  NdbDictionary::Dictionary * dict = pNdb->getDictionary();
+
+  const NdbDictionary::Index* pIdx= dict->getIndex(pkIdxName, pTab->getName());
+  CHK_RET_FAILED(pIdx != 0);
+
+  const NdbRecord * pRowRecord = pTab->getDefaultRecord();
+  CHK_RET_FAILED(pRowRecord != 0);
+  const NdbRecord * pIdxRecord = pIdx->getDefaultRecord();
+  CHK_RET_FAILED(pIdxRecord != 0);
+
+  const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
+  Uint8 * pRow = new Uint8[len];
+  bzero(pRow, len);
+
+  HugoCalculator calc(* pTab);
+  calc.equalForRow(pRow, pRowRecord, 0);
+
+  NdbTransaction* pTrans = pNdb->startTransaction();
+  CHK_RET_FAILED(pTrans != 0);
+
+  NdbInterpretedCode code;
+  code.interpret_exit_ok();
+  code.finalise();
+
+  NdbOperation::OperationOptions opts;
+  bzero(&opts, sizeof(opts));
+  opts.optionsPresent = NdbOperation::OperationOptions::OO_INTERPRETED;
+  opts.interpretedCode = &code;
+
+  const NdbOperation * pOp = pTrans->readTuple(pIdxRecord, (char*)pRow,
+                                               pRowRecord, (char*)pRow,
+                                               NdbOperation::LM_Read,
+                                               0,
+                                               &opts,
+                                               sizeof(opts));
+  CHK_RET_FAILED(pOp);
+  int res = pTrans->execute(Commit, AbortOnError);
+
+  CHK_RET_FAILED(res == 0);
+
+  delete [] pRow;
+
+  return NDBT_OK;
+}
 
 NDBT_TESTSUITE(testInterpreter);
 TESTCASE("IncValue32", 
@@ -480,6 +622,13 @@ TESTCASE("NdbErrorOperation", 
   INITIALIZER(runCheckGetNdbErrorOperation);
 }
 #endif
+TESTCASE("InterpretedUKLookup", "")
+{
+  INITIALIZER(runLoadTable);
+  INITIALIZER(createPkIndex);
+  INITIALIZER(runInterpretedUKLookup);
+  INITIALIZER(createPkIndex_Drop);
+}
 NDBT_TESTSUITE_END(testInterpreter);
 
 int main(int argc, const char** argv){

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2011-03-29 19:12:09 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2011-04-05 06:46:48 +0000
@@ -1663,6 +1663,10 @@ max-time: 300
 cmd: testIndex
 args: -n Bug56829 T1
 
+max-time: 300
+cmd: testIndex
+args: -n Bug12315582 T1
+
 max-time: 500
 cmd: testNodeRestart
 args: -n ForceStopAndRestart T1

=== modified file 'storage/ndb/test/src/HugoCalculator.cpp'
--- a/storage/ndb/test/src/HugoCalculator.cpp	2011-02-02 00:40:07 +0000
+++ b/storage/ndb/test/src/HugoCalculator.cpp	2011-04-01 14:34:28 +0000
@@ -445,3 +445,75 @@ HugoCalculator::getUpdatesValue(NDBT_Res
   return pRow->attributeStore(m_updatesCol)->u_32_value();
 }
 
+int
+HugoCalculator::equalForRow(Uint8 * pRow,
+                            const NdbRecord* pRecord,
+                            int rowId)
+{
+  for(int attrId = 0; attrId < m_tab.getNoOfColumns(); attrId++)
+  {
+    const NdbDictionary::Column* attr = m_tab.getColumn(attrId);
+
+    if (attr->getPrimaryKey() == true)
+    {
+      char buf[8000];
+      int len = attr->getSizeInBytes();
+      memset(buf, 0, sizeof(buf));
+      Uint32 real_len;
+      const char * value = calcValue(rowId, attrId, 0, buf,
+                                     len, &real_len);
+      assert(value != 0); // NULLable PK not supported...
+      Uint32 off = 0;
+      bool ret = NdbDictionary::getOffset(pRecord, attrId, off);
+      if (!ret)
+        abort();
+      memcpy(pRow + off, buf, real_len);
+    }
+  }
+  return NDBT_OK;
+}
+
+int
+HugoCalculator::setValues(Uint8 * pRow,
+                          const NdbRecord* pRecord,
+                          int rowId,
+                          int updateVal)
+{
+  int res = equalForRow(pRow, pRecord, rowId);
+  if (res != 0)
+  {
+    return res;
+  }
+
+  for(int attrId = 0; attrId < m_tab.getNoOfColumns(); attrId++)
+  {
+    const NdbDictionary::Column* attr = m_tab.getColumn(attrId);
+
+    if (attr->getPrimaryKey() == false)
+    {
+      char buf[8000];
+      int len = attr->getSizeInBytes();
+      memset(buf, 0, sizeof(buf));
+      Uint32 real_len;
+      const char * value = calcValue(rowId, attrId, updateVal, buf,
+                                     len, &real_len);
+      if (value != 0)
+      {
+        Uint32 off = 0;
+        bool ret = NdbDictionary::getOffset(pRecord, attrId, off);
+        if (!ret)
+          abort();
+        memcpy(pRow + off, buf, real_len);
+        if (attr->getNullable())
+          NdbDictionary::setNull(pRecord, (char*)pRow, attrId, false);
+      }
+      else
+      {
+        assert(attr->getNullable());
+        NdbDictionary::setNull(pRecord, (char*)pRow, attrId, true);
+      }
+    }
+  }
+
+  return NDBT_OK;
+}

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch (jonas:3469 to3470) jonas oreland5 Apr