summaryrefslogtreecommitdiff
path: root/ndb/src/ndbapi/NdbConnection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/src/ndbapi/NdbConnection.cpp')
-rw-r--r--ndb/src/ndbapi/NdbConnection.cpp284
1 files changed, 181 insertions, 103 deletions
diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp
index 9a2995a957e..1457792cf28 100644
--- a/ndb/src/ndbapi/NdbConnection.cpp
+++ b/ndb/src/ndbapi/NdbConnection.cpp
@@ -14,19 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-
-/*****************************************************************************
-Name: NdbConnection.C
-Include:
-Link:
-Author: UABMNST Mona Natterkvist UAB/B/UL
-Date: 970829
-Version: 0.1
-Description: Interface between TIS and NDB
-Documentation:
-Adjust: 971022 UABMNST First version.
-*****************************************************************************/
+#include <ndb_global.h>
#include <NdbOut.hpp>
#include <NdbConnection.hpp>
#include <NdbOperation.hpp>
@@ -95,6 +83,11 @@ NdbConnection::NdbConnection( Ndb* aNdb ) :
theListState = NotInList;
theError.code = 0;
theId = theNdb->theNdbObjectIdMap->map(this);
+
+#define CHECK_SZ(mask, sz) assert((sizeof(mask)/sizeof(mask[0])) == sz)
+
+ CHECK_SZ(m_db_nodes, NdbNodeBitmask::Size);
+ CHECK_SZ(m_failed_db_nodes, NdbNodeBitmask::Size);
}//NdbConnection::NdbConnection()
/*****************************************************************************
@@ -104,7 +97,9 @@ Remark: Deletes the connection object.
*****************************************************************************/
NdbConnection::~NdbConnection()
{
+ DBUG_ENTER("NdbConnection::~NdbConnection");
theNdb->theNdbObjectIdMap->unmap(theId, this);
+ DBUG_VOID_RETURN;
}//NdbConnection::~NdbConnection()
/*****************************************************************************
@@ -155,27 +150,29 @@ NdbConnection::init()
}//NdbConnection::init()
/*****************************************************************************
-setOperationErrorCode(int anErrorCode);
+setOperationErrorCode(int error);
Remark: Sets an error code on the connection object from an
operation object.
*****************************************************************************/
void
-NdbConnection::setOperationErrorCode(int anErrorCode)
+NdbConnection::setOperationErrorCode(int error)
{
- if (theError.code == 0)
- theError.code = anErrorCode;
-}//NdbConnection::setOperationErrorCode()
+ DBUG_ENTER("NdbConnection::setOperationErrorCode");
+ setErrorCode(error);
+ DBUG_VOID_RETURN;
+}
/*****************************************************************************
-setOperationErrorCodeAbort(int anErrorCode);
+setOperationErrorCodeAbort(int error);
Remark: Sets an error code on the connection object from an
operation object.
*****************************************************************************/
void
-NdbConnection::setOperationErrorCodeAbort(int anErrorCode)
+NdbConnection::setOperationErrorCodeAbort(int error)
{
+ DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort");
if (theTransactionIsStarted == false) {
theCommitStatus = Aborted;
} else if ((m_abortOption == AbortOnError) &&
@@ -183,9 +180,9 @@ NdbConnection::setOperationErrorCodeAbort(int anErrorCode)
(theCommitStatus != Aborted)) {
theCommitStatus = NeedAbort;
}//if
- if (theError.code == 0)
- theError.code = anErrorCode;
-}//NdbConnection::setOperationErrorCodeAbort()
+ setErrorCode(error);
+ DBUG_VOID_RETURN;
+}
/*****************************************************************************
setErrorCode(int anErrorCode);
@@ -193,14 +190,20 @@ setErrorCode(int anErrorCode);
Remark: Sets an error indication on the connection object.
*****************************************************************************/
void
-NdbConnection::setErrorCode(int anErrorCode)
+NdbConnection::setErrorCode(int error)
{
+ DBUG_ENTER("NdbConnection::setErrorCode");
+ DBUG_PRINT("enter", ("error: %d, theError.code: %d", error, theError.code));
+
if (theError.code == 0)
- theError.code = anErrorCode;
+ theError.code = error;
+
+ DBUG_VOID_RETURN;
}//NdbConnection::setErrorCode()
int
NdbConnection::restart(){
+ DBUG_ENTER("NdbConnection::restart");
if(theCompletionStatus == CompletedSuccess){
releaseCompletedOperations();
Uint64 tTransid = theNdb->theFirstTransId;
@@ -210,10 +213,13 @@ NdbConnection::restart(){
} else {
theNdb->theFirstTransId = tTransid + 1;
}
+ theCommitStatus = Started;
theCompletionStatus = NotCompleted;
- return 0;
+ theTransactionIsStarted = false;
+ DBUG_RETURN(0);
}
- return -1;
+ DBUG_PRINT("error",("theCompletionStatus != CompletedSuccess"));
+ DBUG_RETURN(-1);
}
/*****************************************************************************
@@ -268,8 +274,12 @@ NdbConnection::execute(ExecType aTypeOfExec,
AbortOption abortOption,
int forceSend)
{
+ DBUG_ENTER("NdbConnection::execute");
+ DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
+ aTypeOfExec, abortOption));
+
if (! theBlobFlag)
- return executeNoBlobs(aTypeOfExec, abortOption, forceSend);
+ DBUG_RETURN(executeNoBlobs(aTypeOfExec, abortOption, forceSend));
/*
* execute prepared ops in batches, as requested by blobs
@@ -303,8 +313,8 @@ NdbConnection::execute(ExecType aTypeOfExec,
tPrepOp = tPrepOp->next();
}
// save rest of prepared ops if batch
- NdbOperation* tRestOp;
- NdbOperation* tLastOp;
+ NdbOperation* tRestOp= 0;
+ NdbOperation* tLastOp= 0;
if (tPrepOp != NULL) {
tRestOp = tPrepOp->next();
tPrepOp->next(NULL);
@@ -352,7 +362,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
}
} while (theFirstOpInList != NULL || tExecType != aTypeOfExec);
- return ret;
+ DBUG_RETURN(ret);
}
int
@@ -360,6 +370,10 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
AbortOption abortOption,
int forceSend)
{
+ DBUG_ENTER("NdbConnection::executeNoBlobs");
+ DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
+ aTypeOfExec, abortOption));
+
//------------------------------------------------------------------------
// We will start by preparing all operations in the transaction defined
// since last execute or since beginning. If this works ok we will continue
@@ -382,7 +396,7 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
*/
ndbout << "This timeout should never occur, execute(..)" << endl;
setOperationErrorCodeAbort(4012); // Error code for "Cluster Failure"
- return -1;
+ DBUG_RETURN(-1);
}//if
/*
@@ -406,13 +420,13 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
}
#endif
if (theReturnStatus == ReturnFailure) {
- return -1;
+ DBUG_RETURN(-1);
}//if
break;
}
}
thePendingBlobOps = 0;
- return 0;
+ DBUG_RETURN(0);
}//NdbConnection::execute()
/*****************************************************************************
@@ -436,9 +450,15 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
void* anyObject,
AbortOption abortOption)
{
+ DBUG_ENTER("NdbConnection::executeAsynchPrepare");
+ DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: %x, anyObject: %x",
+ aTypeOfExec, aCallback, anyObject));
+
/**
* Reset error.code on execute
*/
+ if (theError.code != 0)
+ DBUG_PRINT("enter", ("Resetting error %d on execute", theError.code));
theError.code = 0;
NdbScanOperation* tcOp = m_theFirstScanOperation;
if (tcOp != 0){
@@ -447,7 +467,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
int tReturnCode;
tReturnCode = tcOp->executeCursor(theDBnode);
if (tReturnCode == -1) {
- return;
+ DBUG_VOID_RETURN;
}//if
tcOp = (NdbScanOperation*)tcOp->next();
} // while
@@ -469,28 +489,12 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
theCallbackFunction = aCallback;
theCallbackObject = anyObject;
m_abortOption = abortOption;
- // SendStatusType tSendStatus = theSendStatus;
-
-// if (tSendStatus != InitState) {
-/****************************************************************************
- * The application is obviously doing strange things. We should probably
- * report to the application the problem in some manner. Since we don't have
- * a good way of handling the problem we avoid discovering the problem.
- * Should be handled at some point in time.
- ****************************************************************************/
-// return;
-// }
m_waitForReply = true;
tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this;
theTransArrayIndex = tnoOfPreparedTransactions;
theListState = InPreparedList;
tNdb->theNoOfPreparedTransactions = tnoOfPreparedTransactions + 1;
- if(tCommitStatus == Committed){
- tCommitStatus = Started;
- tTransactionIsStarted = false;
- }
-
if ((tCommitStatus != Started) ||
(aTypeOfExec == Rollback)) {
/*****************************************************************************
@@ -499,7 +503,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* same action.
****************************************************************************/
if (aTypeOfExec == Rollback) {
- if (theTransactionIsStarted == false) {
+ if (theTransactionIsStarted == false || theSimpleState) {
theCommitStatus = Aborted;
theSendStatus = sendCompleted;
} else {
@@ -508,7 +512,11 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
} else {
theSendStatus = sendABORTfail;
}//if
- return;
+ if (theCommitStatus == Aborted){
+ DBUG_PRINT("exit", ("theCommitStatus: Aborted"));
+ setErrorCode(4350);
+ }
+ DBUG_VOID_RETURN;
}//if
if (tTransactionIsStarted == true) {
if (tLastOp != NULL) {
@@ -520,13 +528,13 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
tLastOp->theCommitIndicator = 1;
}//if
} else {
- if (aTypeOfExec == Commit) {
+ if (aTypeOfExec == Commit && !theSimpleState) {
/**********************************************************************
* A Transaction have been started and no more operations exist.
* We will use the commit method.
*********************************************************************/
theSendStatus = sendCOMMITstate;
- return;
+ DBUG_VOID_RETURN;
} else {
/**********************************************************************
* We need to put it into the array of completed transactions to
@@ -538,7 +546,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* put it into the completed array.
**********************************************************************/
theSendStatus = sendCompleted;
- return; // No Commit with no operations is OK
+ DBUG_VOID_RETURN; // No Commit with no operations is OK
}//if
}//if
} else if (tTransactionIsStarted == false) {
@@ -566,7 +574,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* will put it into the completed array.
***********************************************************************/
theSendStatus = sendCompleted;
- return;
+ DBUG_VOID_RETURN;
}//if
}
@@ -579,7 +587,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId);
if (tReturnCode == -1) {
theSendStatus = sendABORTfail;
- return;
+ DBUG_VOID_RETURN;
}//if
/*************************************************************************
@@ -602,7 +610,9 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
theNoOfOpSent = 0;
theNoOfOpCompleted = 0;
theSendStatus = sendOperations;
- return;
+ NdbNodeBitmask::clear(m_db_nodes);
+ NdbNodeBitmask::clear(m_failed_db_nodes);
+ DBUG_VOID_RETURN;
}//NdbConnection::executeAsynchPrepare()
void NdbConnection::close()
@@ -671,6 +681,8 @@ Remark: Send all operations belonging to this connection.
int
NdbConnection::doSend()
{
+ DBUG_ENTER("NdbConnection::doSend");
+
/*
This method assumes that at least one operation have been defined. This
is ensured by the caller of this routine (=execute).
@@ -693,7 +705,7 @@ NdbConnection::doSend()
theSendStatus = sendTC_OP;
theTransactionIsStarted = true;
tNdb->insert_sent_list(this);
- return 0;
+ DBUG_RETURN(0);
}//case
case sendABORT:
case sendABORTfail:{
@@ -705,20 +717,21 @@ NdbConnection::doSend()
theReturnStatus = ReturnFailure;
}//if
if (sendROLLBACK() == 0) {
- return 0;
+ DBUG_RETURN(0);
}//if
break;
}//case
case sendCOMMITstate:
if (sendCOMMIT() == 0) {
- return 0;
+ DBUG_RETURN(0);
}//if
break;
case sendCompleted:
theNdb->insert_completed_list(this);
- return 0;
+ DBUG_RETURN(0);
default:
- ndbout << "Inconsistent theSendStatus = " << theSendStatus << endl;
+ ndbout << "Inconsistent theSendStatus = "
+ << (Uint32) theSendStatus << endl;
abort();
break;
}//switch
@@ -726,7 +739,7 @@ NdbConnection::doSend()
theReleaseOnClose = true;
theTransactionIsStarted = false;
theCommitStatus = Aborted;
- return -1;
+ DBUG_RETURN(-1);
}//NdbConnection::doSend()
/**************************************************************************
@@ -949,7 +962,7 @@ Remark: Get an operation from NdbOperation object idlelist and
object, synchronous.
*****************************************************************************/
NdbOperation*
-NdbConnection::getNdbOperation(NdbTableImpl * tab, NdbOperation* aNextOp)
+NdbConnection::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp)
{
NdbOperation* tOp;
@@ -995,7 +1008,7 @@ NdbConnection::getNdbOperation(NdbTableImpl * tab, NdbOperation* aNextOp)
return NULL;
}//NdbConnection::getNdbOperation()
-NdbOperation* NdbConnection::getNdbOperation(NdbDictionary::Table * table)
+NdbOperation* NdbConnection::getNdbOperation(const NdbDictionary::Table * table)
{
if (table)
return getNdbOperation(& NdbTableImpl::getImpl(*table));
@@ -1054,8 +1067,8 @@ NdbConnection::getNdbIndexScanOperation(const char* anIndexName,
}
NdbIndexScanOperation*
-NdbConnection::getNdbIndexScanOperation(NdbIndexImpl* index,
- NdbTableImpl* table)
+NdbConnection::getNdbIndexScanOperation(const NdbIndexImpl* index,
+ const NdbTableImpl* table)
{
if (theCommitStatus == Started){
const NdbTableImpl * indexTable = index->getIndexTable();
@@ -1076,8 +1089,8 @@ NdbConnection::getNdbIndexScanOperation(NdbIndexImpl* index,
}//NdbConnection::getNdbIndexScanOperation()
NdbIndexScanOperation*
-NdbConnection::getNdbIndexScanOperation(NdbDictionary::Index * index,
- NdbDictionary::Table * table)
+NdbConnection::getNdbIndexScanOperation(const NdbDictionary::Index * index,
+ const NdbDictionary::Table * table)
{
if (index && table)
return getNdbIndexScanOperation(& NdbIndexImpl::getImpl(*index),
@@ -1097,7 +1110,7 @@ Remark: Get an operation from NdbScanOperation object idlelist and get t
getOperation will set the theTableId in the NdbOperation object, synchronous.
*****************************************************************************/
NdbIndexScanOperation*
-NdbConnection::getNdbScanOperation(NdbTableImpl * tab)
+NdbConnection::getNdbScanOperation(const NdbTableImpl * tab)
{
NdbIndexScanOperation* tOp;
@@ -1105,15 +1118,8 @@ NdbConnection::getNdbScanOperation(NdbTableImpl * tab)
if (tOp == NULL)
goto getNdbOp_error1;
- // Link scan operation into list of cursor operations
- if (m_theLastScanOperation == NULL)
- m_theFirstScanOperation = m_theLastScanOperation = tOp;
- else {
- m_theLastScanOperation->next(tOp);
- m_theLastScanOperation = tOp;
- }
- tOp->next(NULL);
if (tOp->init(tab, this) != -1) {
+ define_scan_op(tOp);
return tOp;
} else {
theNdb->releaseScanOperation(tOp);
@@ -1125,8 +1131,33 @@ getNdbOp_error1:
return NULL;
}//NdbConnection::getNdbScanOperation()
+void
+NdbConnection::remove_list(NdbOperation*& list, NdbOperation* op){
+ NdbOperation* tmp= list;
+ if(tmp == op)
+ list = op->next();
+ else {
+ while(tmp && tmp->next() != op) tmp = tmp->next();
+ if(tmp)
+ tmp->next(op->next());
+ }
+ op->next(NULL);
+}
+
+void
+NdbConnection::define_scan_op(NdbIndexScanOperation * tOp){
+ // Link scan operation into list of cursor operations
+ if (m_theLastScanOperation == NULL)
+ m_theFirstScanOperation = m_theLastScanOperation = tOp;
+ else {
+ m_theLastScanOperation->next(tOp);
+ m_theLastScanOperation = tOp;
+ }
+ tOp->next(NULL);
+}
+
NdbScanOperation*
-NdbConnection::getNdbScanOperation(NdbDictionary::Table * table)
+NdbConnection::getNdbScanOperation(const NdbDictionary::Table * table)
{
if (table)
return getNdbScanOperation(& NdbTableImpl::getImpl(*table));
@@ -1184,8 +1215,8 @@ Remark: Get an operation from NdbIndexOperation object idlelist and get
getOperation will set the theTableId in the NdbIndexOperation object, synchronous.
*****************************************************************************/
NdbIndexOperation*
-NdbConnection::getNdbIndexOperation(NdbIndexImpl * anIndex,
- NdbTableImpl * aTable,
+NdbConnection::getNdbIndexOperation(const NdbIndexImpl * anIndex,
+ const NdbTableImpl * aTable,
NdbOperation* aNextOp)
{
NdbIndexOperation* tOp;
@@ -1228,8 +1259,8 @@ NdbConnection::getNdbIndexOperation(NdbIndexImpl * anIndex,
}//NdbConnection::getNdbIndexOperation()
NdbIndexOperation*
-NdbConnection::getNdbIndexOperation(NdbDictionary::Index * index,
- NdbDictionary::Table * table)
+NdbConnection::getNdbIndexOperation(const NdbDictionary::Index * index,
+ const NdbDictionary::Table * table)
{
if (index && table)
return getNdbIndexOperation(& NdbIndexImpl::getImpl(*index),
@@ -1507,12 +1538,21 @@ from other transactions.
const Uint32* tPtr = (Uint32 *)&keyConf->operations[0];
Uint32 tNoComp = theNoOfOpCompleted;
for (Uint32 i = 0; i < tNoOfOperations ; i++) {
- tOp = theNdb->void2rec(theNdb->int2void(*tPtr));
- tPtr++;
- const Uint32 tAttrInfoLen = *tPtr;
- tPtr++;
+ tOp = theNdb->void2rec(theNdb->int2void(*tPtr++));
+ const Uint32 tAttrInfoLen = *tPtr++;
if (tOp && tOp->checkMagicNumber()) {
- tNoComp += tOp->execTCOPCONF(tAttrInfoLen);
+ Uint32 done = tOp->execTCOPCONF(tAttrInfoLen);
+ if(tAttrInfoLen > TcKeyConf::SimpleReadBit){
+ Uint32 node = tAttrInfoLen & (~TcKeyConf::SimpleReadBit);
+ NdbNodeBitmask::set(m_db_nodes, node);
+ if(NdbNodeBitmask::get(m_failed_db_nodes, node) && !done)
+ {
+ done = 1;
+ tOp->setErrorCode(4119);
+ theCompletionStatus = CompletedFailure;
+ }
+ }
+ tNoComp += done;
} else {
return -1;
}//if
@@ -1604,6 +1644,10 @@ NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf)
setOperationErrorCodeAbort(4115);
tOp = NULL;
break;
+ case NdbOperation::NotDefined:
+ case NdbOperation::NotDefined2:
+ assert(false);
+ break;
}//if
}//while
theReleaseOnClose = true;
@@ -1762,7 +1806,7 @@ Parameters: aErrorCode: The error code.
Remark: An operation was completed with failure.
*******************************************************************************/
int
-NdbConnection::OpCompleteFailure()
+NdbConnection::OpCompleteFailure(Uint8 abortOption)
{
Uint32 tNoComp = theNoOfOpCompleted;
Uint32 tNoSent = theNoOfOpSent;
@@ -1776,10 +1820,7 @@ NdbConnection::OpCompleteFailure()
//decide the success of the whole transaction since a simple
//operation is not really part of that transaction.
//------------------------------------------------------------------------
- if (theSimpleState == 1) {
- theCommitStatus = NdbConnection::Aborted;
- }//if
- if (m_abortOption == IgnoreError){
+ if (abortOption == IgnoreError){
/**
* There's always a TCKEYCONF when using IgnoreError
*/
@@ -1814,9 +1855,6 @@ NdbConnection::OpCompleteSuccess()
tNoComp++;
theNoOfOpCompleted = tNoComp;
if (tNoComp == tNoSent) { // Last operation completed
- if (theSimpleState == 1) {
- theCommitStatus = NdbConnection::Committed;
- }//if
return 0;
} else if (tNoComp < tNoSent) {
return -1; // Continue waiting for more signals
@@ -1891,14 +1929,14 @@ NdbConnection::printState()
CASE(Connected);
CASE(DisConnecting);
CASE(ConnectFailure);
- default: ndbout << theStatus;
+ default: ndbout << (Uint32) theStatus;
}
switch (theListState) {
CASE(NotInList);
CASE(InPreparedList);
CASE(InSendList);
CASE(InCompletedList);
- default: ndbout << theListState;
+ default: ndbout << (Uint32) theListState;
}
switch (theSendStatus) {
CASE(NotInit);
@@ -1911,7 +1949,7 @@ NdbConnection::printState()
CASE(sendTC_ROLLBACK);
CASE(sendTC_COMMIT);
CASE(sendTC_OP);
- default: ndbout << theSendStatus;
+ default: ndbout << (Uint32) theSendStatus;
}
switch (theCommitStatus) {
CASE(NotStarted);
@@ -1919,16 +1957,56 @@ NdbConnection::printState()
CASE(Committed);
CASE(Aborted);
CASE(NeedAbort);
- default: ndbout << theCommitStatus;
+ default: ndbout << (Uint32) theCommitStatus;
}
switch (theCompletionStatus) {
CASE(NotCompleted);
CASE(CompletedSuccess);
CASE(CompletedFailure);
CASE(DefinitionFailure);
- default: ndbout << theCompletionStatus;
+ default: ndbout << (Uint32) theCompletionStatus;
}
ndbout << endl;
}
#undef CASE
#endif
+
+int
+NdbConnection::report_node_failure(Uint32 id){
+ NdbNodeBitmask::set(m_failed_db_nodes, id);
+ if(!NdbNodeBitmask::get(m_db_nodes, id))
+ {
+ return 0;
+ }
+
+ /**
+ * Arrived
+ * TCKEYCONF TRANSIDAI
+ * 1) - -
+ * 2) - X
+ * 3) X -
+ * 4) X X
+ */
+ NdbOperation* tmp = theFirstExecOpInList;
+ const Uint32 len = TcKeyConf::SimpleReadBit | id;
+ Uint32 tNoComp = theNoOfOpCompleted;
+ Uint32 tNoSent = theNoOfOpSent;
+ while(tmp != 0)
+ {
+ if(tmp->theReceiver.m_expected_result_length == len &&
+ tmp->theReceiver.m_received_result_length == 0)
+ {
+ tNoComp++;
+ tmp->theError.code = 4119;
+ }
+ tmp = tmp->next();
+ }
+ theNoOfOpCompleted = tNoComp;
+ if(tNoComp == tNoSent)
+ {
+ theError.code = 4119;
+ theCompletionStatus = NdbConnection::CompletedFailure;
+ return 1;
+ }
+ return 0;
+}