ndb - interface change of handling of abort option

1) move AbortOption from NdbTransaction to NdbOperation

2) let each operation have a "default" abort option dependant on
   operation type

   - read - AO_IgnoreError
   - dml - AbortOnError
   - scan take over - AbortOnError

3) Changed default value to execute() from AbortOnError to DefaultAbortOption, which does not change the operations abort-option.

   Another value to execute(AO) is equivalent to setting AO on each operation before calling execute

4) execute() does _only_ return -1 if transaction has been aborted
   otherwise, you need to check each operation for error code
parent 7d54ea6b
...@@ -260,13 +260,14 @@ static int ndb_to_mysql_error(const NdbError *ndberr) ...@@ -260,13 +260,14 @@ static int ndb_to_mysql_error(const NdbError *ndberr)
int execute_no_commit_ignore_no_key(ha_ndbcluster *h, NdbTransaction *trans) int execute_no_commit_ignore_no_key(ha_ndbcluster *h, NdbTransaction *trans)
{ {
int res= trans->execute(NdbTransaction::NoCommit, int res= trans->execute(NdbTransaction::NoCommit,
NdbTransaction::AO_IgnoreError, NdbOperation::AO_IgnoreError,
h->m_force_send); h->m_force_send);
if (res == 0) if (res == -1)
return 0; return -1;
const NdbError &err= trans->getNdbError(); const NdbError &err= trans->getNdbError();
if (err.classification != NdbError::ConstraintViolation && if (err.classification != NdbError::NoError &&
err.classification != NdbError::ConstraintViolation &&
err.classification != NdbError::NoDataFound) err.classification != NdbError::NoDataFound)
return res; return res;
...@@ -286,7 +287,7 @@ int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans, ...@@ -286,7 +287,7 @@ int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans,
return h->m_ignore_no_key ? return h->m_ignore_no_key ?
execute_no_commit_ignore_no_key(h,trans) : execute_no_commit_ignore_no_key(h,trans) :
trans->execute(NdbTransaction::NoCommit, trans->execute(NdbTransaction::NoCommit,
NdbTransaction::AbortOnError, NdbOperation::AbortOnError,
h->m_force_send); h->m_force_send);
} }
...@@ -299,7 +300,7 @@ int execute_commit(ha_ndbcluster *h, NdbTransaction *trans) ...@@ -299,7 +300,7 @@ int execute_commit(ha_ndbcluster *h, NdbTransaction *trans)
return 0; return 0;
#endif #endif
return trans->execute(NdbTransaction::Commit, return trans->execute(NdbTransaction::Commit,
NdbTransaction::AbortOnError, NdbOperation::AbortOnError,
h->m_force_send); h->m_force_send);
} }
...@@ -312,7 +313,7 @@ int execute_commit(THD *thd, NdbTransaction *trans) ...@@ -312,7 +313,7 @@ int execute_commit(THD *thd, NdbTransaction *trans)
return 0; return 0;
#endif #endif
return trans->execute(NdbTransaction::Commit, return trans->execute(NdbTransaction::Commit,
NdbTransaction::AbortOnError, NdbOperation::AbortOnError,
thd->variables.ndb_force_send); thd->variables.ndb_force_send);
} }
...@@ -327,7 +328,7 @@ int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans, ...@@ -327,7 +328,7 @@ int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans,
#endif #endif
h->release_completed_operations(trans, force_release); h->release_completed_operations(trans, force_release);
return trans->execute(NdbTransaction::NoCommit, return trans->execute(NdbTransaction::NoCommit,
NdbTransaction::AO_IgnoreError, NdbOperation::AO_IgnoreError,
h->m_force_send); h->m_force_send);
} }
...@@ -1731,7 +1732,8 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf, ...@@ -1731,7 +1732,8 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf,
ERR_RETURN(trans->getNdbError()); ERR_RETURN(trans->getNdbError());
} }
if (execute_no_commit_ie(this,trans,false) != 0) if ((res = execute_no_commit_ie(this,trans,false)) != 0 ||
op->getNdbError().code)
{ {
table->status= STATUS_NOT_FOUND; table->status= STATUS_NOT_FOUND;
DBUG_RETURN(ndb_err(trans)); DBUG_RETURN(ndb_err(trans));
...@@ -2003,7 +2005,8 @@ int ha_ndbcluster::unique_index_read(const byte *key, ...@@ -2003,7 +2005,8 @@ int ha_ndbcluster::unique_index_read(const byte *key,
if ((res= define_read_attrs(buf, op))) if ((res= define_read_attrs(buf, op)))
DBUG_RETURN(res); DBUG_RETURN(res);
if (execute_no_commit_ie(this,trans,false) != 0) if (execute_no_commit_ie(this,trans,false) != 0 ||
op->getNdbError().code)
{ {
table->status= STATUS_NOT_FOUND; table->status= STATUS_NOT_FOUND;
DBUG_RETURN(ndb_err(trans)); DBUG_RETURN(ndb_err(trans));
...@@ -7742,7 +7745,7 @@ ndb_get_table_statistics(ha_ndbcluster* file, bool report_error, Ndb* ndb, const ...@@ -7742,7 +7745,7 @@ ndb_get_table_statistics(ha_ndbcluster* file, bool report_error, Ndb* ndb, const
(char*)&var_mem); (char*)&var_mem);
if (pTrans->execute(NdbTransaction::NoCommit, if (pTrans->execute(NdbTransaction::NoCommit,
NdbTransaction::AbortOnError, NdbOperation::AbortOnError,
TRUE) == -1) TRUE) == -1)
{ {
error= pTrans->getNdbError(); error= pTrans->getNdbError();
...@@ -8000,7 +8003,6 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, ...@@ -8000,7 +8003,6 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
!op->readTuple(lm) && !op->readTuple(lm) &&
!set_primary_key(op, multi_range_curr->start_key.key) && !set_primary_key(op, multi_range_curr->start_key.key) &&
!define_read_attrs(curr, op) && !define_read_attrs(curr, op) &&
(op->setAbortOption(AO_IgnoreError), TRUE) &&
(!m_use_partition_function || (!m_use_partition_function ||
(op->setPartitionId(part_spec.start_part), true))) (op->setPartitionId(part_spec.start_part), true)))
curr += reclength; curr += reclength;
...@@ -8022,8 +8024,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, ...@@ -8022,8 +8024,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
if ((op= m_active_trans->getNdbIndexOperation(unique_idx, tab)) && if ((op= m_active_trans->getNdbIndexOperation(unique_idx, tab)) &&
!op->readTuple(lm) && !op->readTuple(lm) &&
!set_index_key(op, key_info, multi_range_curr->start_key.key) && !set_index_key(op, key_info, multi_range_curr->start_key.key) &&
!define_read_attrs(curr, op) && !define_read_attrs(curr, op))
(op->setAbortOption(AO_IgnoreError), TRUE))
curr += reclength; curr += reclength;
else else
ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError()); ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
......
...@@ -98,6 +98,19 @@ public: ...@@ -98,6 +98,19 @@ public:
#endif #endif
}; };
/**
* How should transaction be handled if operation fails
*
* For READ, default is AO_IgnoreError
* DML, default is AbortOnError
* CommittedRead does _only_ support AO_IgnoreError
*/
enum AbortOption {
DefaultAbortOption = -1,///< Use default as specified by op-type
AbortOnError = 0, ///< Abort transaction on failed operation
AO_IgnoreError = 2 ///< Transaction continues on failed operation
};
/** /**
* Define the NdbOperation to be a standard operation of type insertTuple. * Define the NdbOperation to be a standard operation of type insertTuple.
* When calling NdbTransaction::execute, this operation * When calling NdbTransaction::execute, this operation
...@@ -777,8 +790,13 @@ public: ...@@ -777,8 +790,13 @@ public:
*/ */
LockMode getLockMode() const { return theLockMode; } LockMode getLockMode() const { return theLockMode; }
/**
* Get/set abort option
*/
AbortOption getAbortOption() const;
int setAbortOption(AbortOption);
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
void setAbortOption(Int8 ao) { m_abortOption = ao; }
/** /**
* Set/get partition key * Set/get partition key
...@@ -857,7 +875,8 @@ protected: ...@@ -857,7 +875,8 @@ protected:
int doSend(int ProcessorId, Uint32 lastFlag); int doSend(int ProcessorId, Uint32 lastFlag);
virtual int prepareSend(Uint32 TC_ConnectPtr, virtual int prepareSend(Uint32 TC_ConnectPtr,
Uint64 TransactionId); Uint64 TransactionId,
AbortOption);
virtual void setLastFlag(NdbApiSignal* signal, Uint32 lastFlag); virtual void setLastFlag(NdbApiSignal* signal, Uint32 lastFlag);
int prepareSendInterpreted(); // Help routine to prepare* int prepareSendInterpreted(); // Help routine to prepare*
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "NdbError.hpp" #include "NdbError.hpp"
#include "NdbDictionary.hpp" #include "NdbDictionary.hpp"
#include "Ndb.hpp" #include "Ndb.hpp"
#include "NdbOperation.hpp"
class NdbTransaction; class NdbTransaction;
class NdbOperation; class NdbOperation;
...@@ -45,11 +46,12 @@ typedef void (* NdbAsynchCallback)(int, NdbTransaction*, void*); ...@@ -45,11 +46,12 @@ typedef void (* NdbAsynchCallback)(int, NdbTransaction*, void*);
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
enum AbortOption { enum AbortOption {
CommitIfFailFree= 0, DefaultAbortOption = NdbOperation::DefaultAbortOption,
TryCommit= 0, CommitIfFailFree = NdbOperation::AbortOnError,
AbortOnError= 0, TryCommit = NdbOperation::AbortOnError,
CommitAsMuchAsPossible= 2, AbortOnError= NdbOperation::AbortOnError,
AO_IgnoreError= 2 CommitAsMuchAsPossible = NdbOperation::AO_IgnoreError,
AO_IgnoreError= NdbOperation::AO_IgnoreError
}; };
enum ExecType { enum ExecType {
NoExecTypeDef = -1, NoExecTypeDef = -1,
...@@ -145,20 +147,6 @@ class NdbTransaction ...@@ -145,20 +147,6 @@ class NdbTransaction
public: public:
/**
* Commit type of transaction
*/
enum AbortOption {
AbortOnError= ///< Abort transaction on failed operation
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
::AbortOnError
#endif
,AO_IgnoreError= ///< Transaction continues on failed operation
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
::AO_IgnoreError
#endif
};
/** /**
* Execution type of transaction * Execution type of transaction
*/ */
...@@ -317,13 +305,15 @@ public: ...@@ -317,13 +305,15 @@ public:
* @return 0 if successful otherwise -1. * @return 0 if successful otherwise -1.
*/ */
int execute(ExecType execType, int execute(ExecType execType,
AbortOption abortOption = AbortOnError, NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
int force = 0 ); int force = 0 );
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
int execute(::ExecType execType, int execute(::ExecType execType,
::AbortOption abortOption = ::AbortOnError, ::AbortOption abortOption = ::DefaultAbortOption,
int force = 0 ) int force = 0 ) {
{ return execute ((ExecType)execType,(AbortOption)abortOption,force); } return execute ((ExecType)execType,
(NdbOperation::AbortOption)abortOption,
force); }
#endif #endif
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
...@@ -354,14 +344,14 @@ public: ...@@ -354,14 +344,14 @@ public:
void executeAsynchPrepare(ExecType execType, void executeAsynchPrepare(ExecType execType,
NdbAsynchCallback callback, NdbAsynchCallback callback,
void* anyObject, void* anyObject,
AbortOption abortOption = AbortOnError); NdbOperation::AbortOption = NdbOperation::DefaultAbortOption);
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
void executeAsynchPrepare(::ExecType execType, void executeAsynchPrepare(::ExecType execType,
NdbAsynchCallback callback, NdbAsynchCallback callback,
void* anyObject, void* anyObject,
::AbortOption abortOption = ::AbortOnError) ::AbortOption ao = ::DefaultAbortOption) {
{ executeAsynchPrepare((ExecType)execType, callback, anyObject, executeAsynchPrepare((ExecType)execType, callback, anyObject,
(AbortOption)abortOption); } (NdbOperation::AbortOption)ao); }
#endif #endif
/** /**
...@@ -380,14 +370,14 @@ public: ...@@ -380,14 +370,14 @@ public:
void executeAsynch(ExecType aTypeOfExec, void executeAsynch(ExecType aTypeOfExec,
NdbAsynchCallback aCallback, NdbAsynchCallback aCallback,
void* anyObject, void* anyObject,
AbortOption abortOption = AbortOnError); NdbOperation::AbortOption = NdbOperation::DefaultAbortOption);
#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED #ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED
void executeAsynch(::ExecType aTypeOfExec, void executeAsynch(::ExecType aTypeOfExec,
NdbAsynchCallback aCallback, NdbAsynchCallback aCallback,
void* anyObject, void* anyObject,
::AbortOption abortOption= ::AbortOnError) ::AbortOption abortOption= ::DefaultAbortOption)
{ executeAsynch((ExecType)aTypeOfExec, aCallback, anyObject, { executeAsynch((ExecType)aTypeOfExec, aCallback, anyObject,
(AbortOption)abortOption); } (NdbOperation::AbortOption)abortOption); }
#endif #endif
#endif #endif
/** /**
...@@ -589,7 +579,7 @@ private: ...@@ -589,7 +579,7 @@ private:
void init(); // Initialize connection object for new transaction void init(); // Initialize connection object for new transaction
int executeNoBlobs(ExecType execType, int executeNoBlobs(ExecType execType,
AbortOption abortOption = AbortOnError, NdbOperation::AbortOption = NdbOperation::DefaultAbortOption,
int force = 0 ); int force = 0 );
/** /**
...@@ -643,7 +633,7 @@ private: ...@@ -643,7 +633,7 @@ private:
int sendCOMMIT(); // Send a TC_COMMITREQ signal; int sendCOMMIT(); // Send a TC_COMMITREQ signal;
void setGCI(int GCI); // Set the global checkpoint identity void setGCI(int GCI); // Set the global checkpoint identity
int OpCompleteFailure(Uint8 abortoption, bool setFailure = true); int OpCompleteFailure(NdbOperation*);
int OpCompleteSuccess(); int OpCompleteSuccess();
void CompletedOperations(); // Move active ops to list of completed void CompletedOperations(); // Move active ops to list of completed
...@@ -733,7 +723,6 @@ private: ...@@ -733,7 +723,6 @@ private:
Uint32 theNoOfOpSent; // How many operations have been sent Uint32 theNoOfOpSent; // How many operations have been sent
Uint32 theNoOfOpCompleted; // How many operations have completed Uint32 theNoOfOpCompleted; // How many operations have completed
Uint32 theNoOfOpFetched; // How many operations was actually fetched
Uint32 theMyRef; // Our block reference Uint32 theMyRef; // Our block reference
Uint32 theTCConPtr; // Transaction Co-ordinator connection pointer. Uint32 theTCConPtr; // Transaction Co-ordinator connection pointer.
Uint64 theTransactionId; // theTransactionId of the transaction Uint64 theTransactionId; // theTransactionId of the transaction
...@@ -757,7 +746,6 @@ private: ...@@ -757,7 +746,6 @@ private:
bool theTransactionIsStarted; bool theTransactionIsStarted;
bool theInUseState; bool theInUseState;
bool theSimpleState; bool theSimpleState;
Uint8 m_abortOption; // Type of commi
enum ListState { enum ListState {
NotInList, NotInList,
......
...@@ -1134,7 +1134,7 @@ NdbBlob::readTableParts(char* buf, Uint32 part, Uint32 count) ...@@ -1134,7 +1134,7 @@ NdbBlob::readTableParts(char* buf, Uint32 part, Uint32 count)
setErrorCode(tOp); setErrorCode(tOp);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
tOp->m_abortOption = NdbTransaction::AbortOnError; tOp->m_abortOption = NdbOperation::AbortOnError;
buf += thePartSize; buf += thePartSize;
n++; n++;
thePendingBlobOps |= (1 << NdbOperation::ReadRequest); thePendingBlobOps |= (1 << NdbOperation::ReadRequest);
...@@ -1170,7 +1170,7 @@ NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count) ...@@ -1170,7 +1170,7 @@ NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
setErrorCode(tOp); setErrorCode(tOp);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
tOp->m_abortOption = NdbTransaction::AbortOnError; tOp->m_abortOption = NdbOperation::AbortOnError;
buf += thePartSize; buf += thePartSize;
n++; n++;
thePendingBlobOps |= (1 << NdbOperation::InsertRequest); thePendingBlobOps |= (1 << NdbOperation::InsertRequest);
...@@ -1194,7 +1194,7 @@ NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count) ...@@ -1194,7 +1194,7 @@ NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count)
setErrorCode(tOp); setErrorCode(tOp);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
tOp->m_abortOption = NdbTransaction::AbortOnError; tOp->m_abortOption = NdbOperation::AbortOnError;
buf += thePartSize; buf += thePartSize;
n++; n++;
thePendingBlobOps |= (1 << NdbOperation::UpdateRequest); thePendingBlobOps |= (1 << NdbOperation::UpdateRequest);
...@@ -1217,7 +1217,7 @@ NdbBlob::deleteParts(Uint32 part, Uint32 count) ...@@ -1217,7 +1217,7 @@ NdbBlob::deleteParts(Uint32 part, Uint32 count)
setErrorCode(tOp); setErrorCode(tOp);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
tOp->m_abortOption = NdbTransaction::AbortOnError; tOp->m_abortOption = NdbOperation::AbortOnError;
n++; n++;
thePendingBlobOps |= (1 << NdbOperation::DeleteRequest); thePendingBlobOps |= (1 << NdbOperation::DeleteRequest);
theNdbCon->thePendingBlobOps |= (1 << NdbOperation::DeleteRequest); theNdbCon->thePendingBlobOps |= (1 << NdbOperation::DeleteRequest);
...@@ -1253,7 +1253,7 @@ NdbBlob::deletePartsUnknown(Uint32 part) ...@@ -1253,7 +1253,7 @@ NdbBlob::deletePartsUnknown(Uint32 part)
setErrorCode(tOp); setErrorCode(tOp);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
tOp->m_abortOption= NdbTransaction::AO_IgnoreError; tOp->m_abortOption= NdbOperation::AO_IgnoreError;
n++; n++;
} }
DBUG_PRINT("info", ("bat=%u", bat)); DBUG_PRINT("info", ("bat=%u", bat));
...@@ -1589,7 +1589,7 @@ NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch) ...@@ -1589,7 +1589,7 @@ NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch)
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (isWriteOp()) { if (isWriteOp()) {
tOp->m_abortOption = NdbTransaction::AO_IgnoreError; tOp->m_abortOption = NdbOperation::AO_IgnoreError;
} }
theHeadInlineReadOp = tOp; theHeadInlineReadOp = tOp;
// execute immediately // execute immediately
...@@ -1635,7 +1635,7 @@ NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch) ...@@ -1635,7 +1635,7 @@ NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch)
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (isWriteOp()) { if (isWriteOp()) {
tOp->m_abortOption = NdbTransaction::AO_IgnoreError; tOp->m_abortOption = NdbOperation::AO_IgnoreError;
} }
theHeadInlineReadOp = tOp; theHeadInlineReadOp = tOp;
// execute immediately // execute immediately
...@@ -1808,7 +1808,7 @@ NdbBlob::postExecute(NdbTransaction::ExecType anExecType) ...@@ -1808,7 +1808,7 @@ NdbBlob::postExecute(NdbTransaction::ExecType anExecType)
setErrorCode(NdbBlobImpl::ErrAbort); setErrorCode(NdbBlobImpl::ErrAbort);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
tOp->m_abortOption = NdbTransaction::AbortOnError; tOp->m_abortOption = NdbOperation::AbortOnError;
DBUG_PRINT("info", ("added op to update head+inline")); DBUG_PRINT("info", ("added op to update head+inline"));
} }
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -1838,7 +1838,7 @@ NdbBlob::preCommit() ...@@ -1838,7 +1838,7 @@ NdbBlob::preCommit()
setErrorCode(NdbBlobImpl::ErrAbort); setErrorCode(NdbBlobImpl::ErrAbort);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
tOp->m_abortOption = NdbTransaction::AbortOnError; tOp->m_abortOption = NdbOperation::AbortOnError;
DBUG_PRINT("info", ("added op to update head+inline")); DBUG_PRINT("info", ("added op to update head+inline"));
} }
} }
......
...@@ -428,7 +428,7 @@ NdbIndexStat::records_in_range(const NdbDictionary::Index* index, NdbIndexScanOp ...@@ -428,7 +428,7 @@ NdbIndexStat::records_in_range(const NdbDictionary::Index* index, NdbIndexScanOp
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (trans->execute(NdbTransaction::NoCommit, if (trans->execute(NdbTransaction::NoCommit,
NdbTransaction::AbortOnError, forceSend) == -1) { NdbOperation::AbortOnError, forceSend) == -1) {
m_error = trans->getNdbError(); m_error = trans->getNdbError();
DBUG_PRINT("error", ("trans:%d op:%d", trans->getNdbError().code, DBUG_PRINT("error", ("trans:%d op:%d", trans->getNdbError().code,
op->getNdbError().code)); op->getNdbError().code));
......
...@@ -45,6 +45,7 @@ NdbOperation::insertTuple() ...@@ -45,6 +45,7 @@ NdbOperation::insertTuple()
tNdbCon->theSimpleState = 0; tNdbCon->theSimpleState = 0;
theErrorLine = tErrorLine++; theErrorLine = tErrorLine++;
theLockMode = LM_Exclusive; theLockMode = LM_Exclusive;
m_abortOption = AbortOnError;
return 0; return 0;
} else { } else {
setErrorCode(4200); setErrorCode(4200);
...@@ -65,6 +66,7 @@ NdbOperation::updateTuple() ...@@ -65,6 +66,7 @@ NdbOperation::updateTuple()
theOperationType = UpdateRequest; theOperationType = UpdateRequest;
theErrorLine = tErrorLine++; theErrorLine = tErrorLine++;
theLockMode = LM_Exclusive; theLockMode = LM_Exclusive;
m_abortOption = AbortOnError;
return 0; return 0;
} else { } else {
setErrorCode(4200); setErrorCode(4200);
...@@ -85,12 +87,35 @@ NdbOperation::writeTuple() ...@@ -85,12 +87,35 @@ NdbOperation::writeTuple()
theOperationType = WriteRequest; theOperationType = WriteRequest;
theErrorLine = tErrorLine++; theErrorLine = tErrorLine++;
theLockMode = LM_Exclusive; theLockMode = LM_Exclusive;
m_abortOption = AbortOnError;
return 0; return 0;
} else { } else {
setErrorCode(4200); setErrorCode(4200);
return -1; return -1;
}//if }//if
}//NdbOperation::writeTuple() }//NdbOperation::writeTuple()
/*****************************************************************************
* int deleteTuple();
*****************************************************************************/
int
NdbOperation::deleteTuple()
{
NdbTransaction* tNdbCon = theNdbCon;
int tErrorLine = theErrorLine;
if (theStatus == Init) {
theStatus = OperationDefined;
tNdbCon->theSimpleState = 0;
theOperationType = DeleteRequest;
theErrorLine = tErrorLine++;
theLockMode = LM_Exclusive;
m_abortOption = AbortOnError;
return 0;
} else {
setErrorCode(4200);
return -1;
}//if
}//NdbOperation::deleteTuple()
/****************************************************************************** /******************************************************************************
* int readTuple(); * int readTuple();
*****************************************************************************/ *****************************************************************************/
...@@ -125,6 +150,7 @@ NdbOperation::readTuple() ...@@ -125,6 +150,7 @@ NdbOperation::readTuple()
theOperationType = ReadRequest; theOperationType = ReadRequest;
theErrorLine = tErrorLine++; theErrorLine = tErrorLine++;
theLockMode = LM_Read; theLockMode = LM_Read;
m_abortOption = AO_IgnoreError;
return 0; return 0;
} else { } else {
setErrorCode(4200); setErrorCode(4200);
...@@ -132,27 +158,6 @@ NdbOperation::readTuple() ...@@ -132,27 +158,6 @@ NdbOperation::readTuple()
}//if }//if
}//NdbOperation::readTuple() }//NdbOperation::readTuple()
/*****************************************************************************
* int deleteTuple();
*****************************************************************************/
int
NdbOperation::deleteTuple()
{
NdbTransaction* tNdbCon = theNdbCon;
int tErrorLine = theErrorLine;
if (theStatus == Init) {
theStatus = OperationDefined;
tNdbCon->theSimpleState = 0;
theOperationType = DeleteRequest;
theErrorLine = tErrorLine++;
theLockMode = LM_Exclusive;
return 0;
} else {
setErrorCode(4200);
return -1;
}//if
}//NdbOperation::deleteTuple()
/****************************************************************************** /******************************************************************************
* int readTupleExclusive(); * int readTupleExclusive();
*****************************************************************************/ *****************************************************************************/
...@@ -167,6 +172,7 @@ NdbOperation::readTupleExclusive() ...@@ -167,6 +172,7 @@ NdbOperation::readTupleExclusive()
theOperationType = ReadExclusive; theOperationType = ReadExclusive;
theErrorLine = tErrorLine++; theErrorLine = tErrorLine++;
theLockMode = LM_Exclusive; theLockMode = LM_Exclusive;
m_abortOption = AO_IgnoreError;
return 0; return 0;
} else { } else {
setErrorCode(4200); setErrorCode(4200);
...@@ -223,6 +229,7 @@ NdbOperation::committedRead() ...@@ -223,6 +229,7 @@ NdbOperation::committedRead()
theDirtyIndicator = 1; theDirtyIndicator = 1;
theErrorLine = tErrorLine++; theErrorLine = tErrorLine++;
theLockMode = LM_CommittedRead; theLockMode = LM_CommittedRead;
m_abortOption = AO_IgnoreError;
return 0; return 0;
} else { } else {
setErrorCode(4200); setErrorCode(4200);
...@@ -246,6 +253,7 @@ NdbOperation::dirtyUpdate() ...@@ -246,6 +253,7 @@ NdbOperation::dirtyUpdate()
theDirtyIndicator = 1; theDirtyIndicator = 1;
theErrorLine = tErrorLine++; theErrorLine = tErrorLine++;
theLockMode = LM_CommittedRead; theLockMode = LM_CommittedRead;
m_abortOption = AbortOnError;
return 0; return 0;
} else { } else {
setErrorCode(4200); setErrorCode(4200);
...@@ -269,6 +277,7 @@ NdbOperation::dirtyWrite() ...@@ -269,6 +277,7 @@ NdbOperation::dirtyWrite()
theDirtyIndicator = 1; theDirtyIndicator = 1;
theErrorLine = tErrorLine++; theErrorLine = tErrorLine++;
theLockMode = LM_CommittedRead; theLockMode = LM_CommittedRead;
m_abortOption = AbortOnError;
return 0; return 0;
} else { } else {
setErrorCode(4200); setErrorCode(4200);
...@@ -291,6 +300,7 @@ NdbOperation::interpretedUpdateTuple() ...@@ -291,6 +300,7 @@ NdbOperation::interpretedUpdateTuple()
theAI_LenInCurrAI = 25; theAI_LenInCurrAI = 25;
theLockMode = LM_Exclusive; theLockMode = LM_Exclusive;
theErrorLine = tErrorLine++; theErrorLine = tErrorLine++;
m_abortOption = AbortOnError;
initInterpreter(); initInterpreter();
return 0; return 0;
} else { } else {
...@@ -315,6 +325,7 @@ NdbOperation::interpretedDeleteTuple() ...@@ -315,6 +325,7 @@ NdbOperation::interpretedDeleteTuple()
theErrorLine = tErrorLine++; theErrorLine = tErrorLine++;
theAI_LenInCurrAI = 25; theAI_LenInCurrAI = 25;
theLockMode = LM_Exclusive; theLockMode = LM_Exclusive;
m_abortOption = AbortOnError;
initInterpreter(); initInterpreter();
return 0; return 0;
} else { } else {
......
...@@ -100,7 +100,9 @@ Parameters: aTC_ConnectPtr: the Connect pointer to TC. ...@@ -100,7 +100,9 @@ Parameters: aTC_ConnectPtr: the Connect pointer to TC.
Remark: Puts the the data into TCKEYREQ signal and optional KEYINFO and ATTRINFO signals. Remark: Puts the the data into TCKEYREQ signal and optional KEYINFO and ATTRINFO signals.
***************************************************************************/ ***************************************************************************/
int int
NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) NdbOperation::prepareSend(Uint32 aTC_ConnectPtr,
Uint64 aTransId,
AbortOption ao)
{ {
Uint32 tTransId1, tTransId2; Uint32 tTransId1, tTransId2;
Uint32 tReqInfo; Uint32 tReqInfo;
...@@ -148,8 +150,8 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) ...@@ -148,8 +150,8 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
//------------------------------------------------------------- //-------------------------------------------------------------
TcKeyReq * const tcKeyReq = CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend()); TcKeyReq * const tcKeyReq = CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend());
Uint32 tTableId = m_currentTable->m_id; Uint32 tTableId = m_accessTable->m_id;
Uint32 tSchemaVersion = m_currentTable->m_version; Uint32 tSchemaVersion = m_accessTable->m_version;
tcKeyReq->apiConnectPtr = aTC_ConnectPtr; tcKeyReq->apiConnectPtr = aTC_ConnectPtr;
tcKeyReq->apiOperationPtr = ptr2int(); tcKeyReq->apiOperationPtr = ptr2int();
...@@ -199,16 +201,16 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId) ...@@ -199,16 +201,16 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
OperationType tOperationType = theOperationType; OperationType tOperationType = theOperationType;
Uint32 tTupKeyLen = theTupKeyLen; Uint32 tTupKeyLen = theTupKeyLen;
Uint8 abortOption = Uint8 abortOption = (ao == DefaultAbortOption) ? m_abortOption : ao;
m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption;
tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator); tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
tcKeyReq->setOperationType(tReqInfo, tOperationType); tcKeyReq->setOperationType(tReqInfo, tOperationType);
tcKeyReq->setKeyLength(tReqInfo, tTupKeyLen); tcKeyReq->setKeyLength(tReqInfo, tTupKeyLen);
// A simple read is always ignore error // A simple read is always ignore error
abortOption = tSimpleIndicator ? (Uint8) AO_IgnoreError : abortOption; abortOption = tSimpleState ? AO_IgnoreError : abortOption;
tcKeyReq->setAbortOption(tReqInfo, abortOption); tcKeyReq->setAbortOption(tReqInfo, abortOption);
m_abortOption = abortOption;
Uint8 tDistrKeyIndicator = theDistrKeyIndicator_; Uint8 tDistrKeyIndicator = theDistrKeyIndicator_;
Uint8 tScanIndicator = theScanInfo & 1; Uint8 tScanIndicator = theScanInfo & 1;
...@@ -544,21 +546,16 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal) ...@@ -544,21 +546,16 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
return -1; return -1;
}//if }//if
AbortOption ao = (AbortOption) setErrorCode(aSignal->readData(4));
(m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption); theStatus = Finished;
theReceiver.m_received_result_length = ~0; theReceiver.m_received_result_length = ~0;
theStatus = Finished; // not simple read
// blobs want this if(! (theOperationType == ReadRequest && theSimpleIndicator))
if (m_abortOption != AO_IgnoreError)
{ {
theNdbCon->theReturnStatus = NdbTransaction::ReturnFailure; theNdbCon->OpCompleteFailure(this);
return -1;
} }
theError.code = aSignal->readData(4);
theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), ao);
if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read
return theNdbCon->OpCompleteFailure(ao, m_abortOption != AO_IgnoreError);
/** /**
* If TCKEYCONF has arrived * If TCKEYCONF has arrived
...@@ -566,23 +563,8 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal) ...@@ -566,23 +563,8 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
*/ */
if(theReceiver.m_expected_result_length) if(theReceiver.m_expected_result_length)
{ {
return theNdbCon->OpCompleteFailure(AbortOnError); return theNdbCon->OpCompleteFailure(this);
} }
return -1; return -1;
} }
void
NdbOperation::handleFailedAI_ElemLen()
{
NdbRecAttr* tRecAttr = theReceiver.theFirstRecAttr;
while (tRecAttr != NULL) {
tRecAttr->setNULL();
tRecAttr = tRecAttr->next();
}//while
}//NdbOperation::handleFailedAI_ElemLen()
...@@ -996,6 +996,7 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbTransaction* pTrans) ...@@ -996,6 +996,7 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbTransaction* pTrans)
newOp->theTupKeyLen = len; newOp->theTupKeyLen = len;
newOp->theOperationType = opType; newOp->theOperationType = opType;
newOp->m_abortOption = AbortOnError;
switch (opType) { switch (opType) {
case (ReadRequest): case (ReadRequest):
newOp->theLockMode = theLockMode; newOp->theLockMode = theLockMode;
......
...@@ -57,7 +57,6 @@ NdbTransaction::NdbTransaction( Ndb* aNdb ) : ...@@ -57,7 +57,6 @@ NdbTransaction::NdbTransaction( Ndb* aNdb ) :
theCompletedLastOp(NULL), theCompletedLastOp(NULL),
theNoOfOpSent(0), theNoOfOpSent(0),
theNoOfOpCompleted(0), theNoOfOpCompleted(0),
theNoOfOpFetched(0),
theMyRef(0), theMyRef(0),
theTCConPtr(0), theTCConPtr(0),
theTransactionId(0), theTransactionId(0),
...@@ -132,7 +131,6 @@ NdbTransaction::init() ...@@ -132,7 +131,6 @@ NdbTransaction::init()
theNdb->theImpl->m_ndb_cluster_connection.get_latest_trans_gci(); theNdb->theImpl->m_ndb_cluster_connection.get_latest_trans_gci();
theCommitStatus = Started; theCommitStatus = Started;
theCompletionStatus = NotCompleted; theCompletionStatus = NotCompleted;
m_abortOption = AbortOnError;
theError.code = 0; theError.code = 0;
theErrorLine = 0; theErrorLine = 0;
...@@ -177,12 +175,9 @@ void ...@@ -177,12 +175,9 @@ void
NdbTransaction::setOperationErrorCodeAbort(int error, int abortOption) NdbTransaction::setOperationErrorCodeAbort(int error, int abortOption)
{ {
DBUG_ENTER("NdbTransaction::setOperationErrorCodeAbort"); DBUG_ENTER("NdbTransaction::setOperationErrorCodeAbort");
if (abortOption == -1)
abortOption = m_abortOption;
if (theTransactionIsStarted == false) { if (theTransactionIsStarted == false) {
theCommitStatus = Aborted; theCommitStatus = Aborted;
} else if ((abortOption == AbortOnError) && } else if ((theCommitStatus != Committed) &&
(theCommitStatus != Committed) &&
(theCommitStatus != Aborted)) { (theCommitStatus != Aborted)) {
theCommitStatus = NeedAbort; theCommitStatus = NeedAbort;
}//if }//if
...@@ -264,8 +259,8 @@ Remark: Initialise connection object for new transaction. ...@@ -264,8 +259,8 @@ Remark: Initialise connection object for new transaction.
*****************************************************************************/ *****************************************************************************/
int int
NdbTransaction::execute(ExecType aTypeOfExec, NdbTransaction::execute(ExecType aTypeOfExec,
AbortOption abortOption, NdbOperation::AbortOption abortOption,
int forceSend) int forceSend)
{ {
NdbError savedError= theError; NdbError savedError= theError;
DBUG_ENTER("NdbTransaction::execute"); DBUG_ENTER("NdbTransaction::execute");
...@@ -355,40 +350,14 @@ NdbTransaction::execute(ExecType aTypeOfExec, ...@@ -355,40 +350,14 @@ NdbTransaction::execute(ExecType aTypeOfExec,
theCompletedLastOp = NULL; theCompletedLastOp = NULL;
} }
if (executeNoBlobs(tExecType, abortOption, forceSend) == -1) if (executeNoBlobs(tExecType,
NdbOperation::DefaultAbortOption,
forceSend) == -1)
{ {
ret = -1;
if(savedError.code==0) if(savedError.code==0)
savedError= theError; savedError= theError;
/** DBUG_RETURN(-1);
* If AO_IgnoreError, error codes arent always set on individual
* operations, making postExecute impossible
*/
if (abortOption == AO_IgnoreError)
{
if (theCompletedFirstOp != NULL)
{
if (tCompletedFirstOp != NULL)
{
tCompletedLastOp->next(theCompletedFirstOp);
theCompletedFirstOp = tCompletedFirstOp;
}
}
else
{
theCompletedFirstOp = tCompletedFirstOp;
theCompletedLastOp = tCompletedLastOp;
}
if (tPrepOp != NULL && tRestOp != NULL) {
if (theFirstOpInList == NULL)
theFirstOpInList = tRestOp;
else
theLastOpInList->next(tRestOp);
theLastOpInList = tLastOp;
}
DBUG_RETURN(-1);
}
} }
#ifdef ndb_api_crash_on_complex_blob_abort #ifdef ndb_api_crash_on_complex_blob_abort
...@@ -448,9 +417,9 @@ NdbTransaction::execute(ExecType aTypeOfExec, ...@@ -448,9 +417,9 @@ NdbTransaction::execute(ExecType aTypeOfExec,
} }
int int
NdbTransaction::executeNoBlobs(ExecType aTypeOfExec, NdbTransaction::executeNoBlobs(NdbTransaction::ExecType aTypeOfExec,
AbortOption abortOption, NdbOperation::AbortOption abortOption,
int forceSend) int forceSend)
{ {
DBUG_ENTER("NdbTransaction::executeNoBlobs"); DBUG_ENTER("NdbTransaction::executeNoBlobs");
DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d", DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
...@@ -528,10 +497,10 @@ Parameters : aTypeOfExec: Type of execute. ...@@ -528,10 +497,10 @@ Parameters : aTypeOfExec: Type of execute.
Remark: Prepare a part of a transaction in an asynchronous manner. Remark: Prepare a part of a transaction in an asynchronous manner.
*****************************************************************************/ *****************************************************************************/
void void
NdbTransaction::executeAsynchPrepare( ExecType aTypeOfExec, NdbTransaction::executeAsynchPrepare(NdbTransaction::ExecType aTypeOfExec,
NdbAsynchCallback aCallback, NdbAsynchCallback aCallback,
void* anyObject, void* anyObject,
AbortOption abortOption) NdbOperation::AbortOption abortOption)
{ {
DBUG_ENTER("NdbTransaction::executeAsynchPrepare"); DBUG_ENTER("NdbTransaction::executeAsynchPrepare");
DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: 0x%lx, anyObject: Ox%lx", DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: 0x%lx, anyObject: Ox%lx",
...@@ -571,7 +540,6 @@ NdbTransaction::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -571,7 +540,6 @@ NdbTransaction::executeAsynchPrepare( ExecType aTypeOfExec,
theReturnStatus = ReturnSuccess; theReturnStatus = ReturnSuccess;
theCallbackFunction = aCallback; theCallbackFunction = aCallback;
theCallbackObject = anyObject; theCallbackObject = anyObject;
m_abortOption = abortOption;
m_waitForReply = true; m_waitForReply = true;
tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this; tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this;
theTransArrayIndex = tnoOfPreparedTransactions; theTransArrayIndex = tnoOfPreparedTransactions;
...@@ -666,8 +634,7 @@ NdbTransaction::executeAsynchPrepare( ExecType aTypeOfExec, ...@@ -666,8 +634,7 @@ NdbTransaction::executeAsynchPrepare( ExecType aTypeOfExec,
while (tOp) { while (tOp) {
int tReturnCode; int tReturnCode;
NdbOperation* tNextOp = tOp->next(); NdbOperation* tNextOp = tOp->next();
tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId, abortOption);
tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId);
if (tReturnCode == -1) { if (tReturnCode == -1) {
theSendStatus = sendABORTfail; theSendStatus = sendABORTfail;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -1800,14 +1767,8 @@ from other transactions. ...@@ -1800,14 +1767,8 @@ from other transactions.
} }
} else if ((tNoComp >= tNoSent) && } else if ((tNoComp >= tNoSent) &&
(theLastExecOpInList->theCommitIndicator == 1)){ (theLastExecOpInList->theCommitIndicator == 1)){
if (m_abortOption == AO_IgnoreError && theError.code != 0){
/**
* There's always a TCKEYCONF when using IgnoreError
*/
return -1;
}
/**********************************************************************/ /**********************************************************************/
// We sent the transaction with Commit flag set and received a CONF with // We sent the transaction with Commit flag set and received a CONF with
// no Commit flag set. This is clearly an anomaly. // no Commit flag set. This is clearly an anomaly.
...@@ -1981,13 +1942,6 @@ NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf, ...@@ -1981,13 +1942,6 @@ NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf,
} else if ((tNoComp >= tNoSent) && } else if ((tNoComp >= tNoSent) &&
(theLastExecOpInList->theCommitIndicator == 1)){ (theLastExecOpInList->theCommitIndicator == 1)){
if (m_abortOption == AO_IgnoreError && theError.code != 0){
/**
* There's always a TCKEYCONF when using IgnoreError
*/
return -1;
}
/**********************************************************************/ /**********************************************************************/
// We sent the transaction with Commit flag set and received a CONF with // We sent the transaction with Commit flag set and received a CONF with
// no Commit flag set. This is clearly an anomaly. // no Commit flag set. This is clearly an anomaly.
...@@ -2011,41 +1965,6 @@ NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf, ...@@ -2011,41 +1965,6 @@ NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf,
return -1; return -1;
}//NdbTransaction::receiveTCINDXCONF() }//NdbTransaction::receiveTCINDXCONF()
/*****************************************************************************
int receiveTCINDXREF( NdbApiSignal* aSignal)
Return Value: Return 0 : send was succesful.
Return -1: In all other case.
Parameters: aSignal: the signal object that contains the
TCINDXREF signal from TC.
Remark: Handles the reception of the TCINDXREF signal.
*****************************************************************************/
int
NdbTransaction::receiveTCINDXREF( NdbApiSignal* aSignal)
{
if(checkState_TransId(aSignal->getDataPtr()+1)){
theError.code = aSignal->readData(4); // Override any previous errors
/**********************************************************************/
/* A serious error has occured. This could be due to deadlock or */
/* lack of resources or simply a programming error in NDB. This */
/* transaction will be aborted. Actually it has already been */
/* and we only need to report completion and return with the */
/* error code to the application. */
/**********************************************************************/
theCompletionStatus = NdbTransaction::CompletedFailure;
theCommitStatus = NdbTransaction::Aborted;
theReturnStatus = NdbTransaction::ReturnFailure;
return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
}
return -1;
}//NdbTransaction::receiveTCINDXREF()
/******************************************************************************* /*******************************************************************************
int OpCompletedFailure(); int OpCompletedFailure();
...@@ -2055,36 +1974,15 @@ Parameters: aErrorCode: The error code. ...@@ -2055,36 +1974,15 @@ Parameters: aErrorCode: The error code.
Remark: An operation was completed with failure. Remark: An operation was completed with failure.
*******************************************************************************/ *******************************************************************************/
int int
NdbTransaction::OpCompleteFailure(Uint8 abortOption, bool setFailure) NdbTransaction::OpCompleteFailure(NdbOperation* op)
{ {
Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoComp = theNoOfOpCompleted;
Uint32 tNoSent = theNoOfOpSent; Uint32 tNoSent = theNoOfOpSent;
if (setFailure)
theCompletionStatus = NdbTransaction::CompletedFailure;
tNoComp++; tNoComp++;
theNoOfOpCompleted = tNoComp; theNoOfOpCompleted = tNoComp;
if (tNoComp == tNoSent) {
//------------------------------------------------------------------------ return (tNoComp == tNoSent) ? 0 : -1;
//If the transaction consists of only simple reads we can set
//Commit state Aborted. Otherwise this simple operation cannot
//decide the success of the whole transaction since a simple
//operation is not really part of that transaction.
//------------------------------------------------------------------------
if (abortOption == AO_IgnoreError){
/**
* There's always a TCKEYCONF when using IgnoreError
*/
return -1;
}
return 0; // Last operation received
} else if (tNoComp > tNoSent) {
setOperationErrorCodeAbort(4113); // Too many operations,
// stop waiting for more
return 0;
} else {
return -1; // Continue waiting for more signals
}//if
}//NdbTransaction::OpCompleteFailure() }//NdbTransaction::OpCompleteFailure()
/****************************************************************************** /******************************************************************************
......
...@@ -107,8 +107,8 @@ public: ...@@ -107,8 +107,8 @@ public:
NDBT_ResultRow& get_row(Uint32 idx) { return *rows[idx];} NDBT_ResultRow& get_row(Uint32 idx) { return *rows[idx];}
int execute_async(Ndb*, NdbTransaction::ExecType, NdbTransaction::AbortOption = NdbTransaction::AbortOnError); int execute_async(Ndb*, NdbTransaction::ExecType, NdbOperation::AbortOption = NdbOperation::AbortOnError);
int execute_async_prepare(Ndb*, NdbTransaction::ExecType, NdbTransaction::AbortOption = NdbTransaction::AbortOnError); int execute_async_prepare(Ndb*, NdbTransaction::ExecType, NdbOperation::AbortOption = NdbOperation::AbortOnError);
int wait_async(Ndb*, int timeout = -1); int wait_async(Ndb*, int timeout = -1);
......
...@@ -1250,6 +1250,274 @@ int runScan_4006(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -1250,6 +1250,274 @@ int runScan_4006(NDBT_Context* ctx, NDBT_Step* step){
return result; return result;
} }
char pkIdxName[255];
int createPkIndex(NDBT_Context* ctx, NDBT_Step* step){
bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
const NdbDictionary::Table* pTab = ctx->getTab();
Ndb* pNdb = GETNDB(step);
bool logged = ctx->getProperty("LoggedIndexes", 1);
// 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 (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);
// Drop index
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;
}
static
int
op_row(NdbTransaction* pTrans, HugoOperations& hugoOps,
const NdbDictionary::Table* pTab, int op, int row)
{
NdbOperation * pOp = 0;
switch(op){
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
pOp = pTrans->getNdbOperation(pTab->getName());
break;
case 9:
return 0;
case 6:
case 7:
case 8:
case 10:
case 11:
pOp = pTrans->getNdbIndexOperation(pkIdxName, pTab->getName());
default:
break;
}
switch(op){
case 0:
case 6:
pOp->readTuple();
break;
case 1:
case 7:
pOp->committedRead();
break;
case 2:
case 8:
pOp->readTupleExclusive();
break;
case 3:
case 9:
pOp->insertTuple();
break;
case 4:
case 10:
pOp->updateTuple();
break;
case 5:
case 11:
pOp->deleteTuple();
break;
default:
abort();
}
for(int a = 0; a<pTab->getNoOfColumns(); a++){
if (pTab->getColumn(a)->getPrimaryKey() == true){
if(hugoOps.equalForAttr(pOp, a, row) != 0){
return NDBT_FAILED;
}
}
}
switch(op){
case 0:
case 1:
case 2:
case 6:
case 7:
case 8:
for(int a = 0; a<pTab->getNoOfColumns(); a++){
pOp->getValue(a);
}
break;
case 3:
case 4:
case 10:
for(int a = 0; a<pTab->getNoOfColumns(); a++){
if (pTab->getColumn(a)->getPrimaryKey() == false){
if(hugoOps.setValueForAttr(pOp, a, row, 2) != 0){
return NDBT_FAILED;
}
}
}
break;
case 5:
case 11:
pOp->deleteTuple();
break;
case 9:
default:
abort();
}
return NDBT_OK;
}
static void print(int op)
{
const char * str = 0;
switch(op){
case 0: str = "pk read-sh"; break;
case 1: str = "pk read-nl"; break;
case 2: str = "pk read-ex"; break;
case 3: str = "pk insert "; break;
case 4: str = "pk update "; break;
case 5: str = "pk delete "; break;
case 6: str = "uk read-sh"; break;
case 7: str = "uk read-nl"; break;
case 8: str = "uk read-ex"; break;
case 9: str = "noop "; break;
case 10: str = "uk update "; break;
case 11: str = "uk delete "; break;
default:
abort();
}
printf("%s ", str);
}
int
runTestIgnoreError(NDBT_Context* ctx, NDBT_Step* step)
{
int result = NDBT_OK;
Uint32 loops = ctx->getNumRecords();
const NdbDictionary::Table* pTab = ctx->getTab();
HugoOperations hugoOps(*pTab);
HugoTransactions hugoTrans(*pTab);
Ndb* pNdb = GETNDB(step);
struct {
ExecType et;
AbortOption ao;
} tests[] = {
{ Commit, AbortOnError },
{ Commit, AO_IgnoreError },
{ NoCommit, AbortOnError },
{ NoCommit, AO_IgnoreError },
};
printf("case: <op1> <op2> c/nc ao/ie\n");
Uint32 tno = 0;
for (Uint32 op1 = 0; op1 < 12; op1++)
{
for (Uint32 op2 = op1; op2 < 12; op2++)
{
int ret;
NdbTransaction* pTrans = 0;
for (Uint32 i = 0; i<4; i++, tno++)
{
if (loops != 1000 && loops != tno)
continue;
ExecType et = tests[i].et;
AbortOption ao = tests[i].ao;
printf("%.3d : ", tno);
print(op1);
print(op2);
switch(et){
case Commit: printf("c "); break;
case NoCommit: printf("nc "); break;
}
switch(ao){
case AbortOnError: printf("aoe "); break;
case AO_IgnoreError: printf("ie "); break;
}
printf(": ");
hugoTrans.loadTable(pNdb, 1);
pTrans = pNdb->startTransaction();
op_row(pTrans, hugoOps, pTab, op1, 0);
ret = pTrans->execute(et, ao);
pTrans->close();
printf("%d ", ret);
hugoTrans.clearTable(pNdb);
hugoTrans.loadTable(pNdb, 1);
pTrans = pNdb->startTransaction();
op_row(pTrans, hugoOps, pTab, op1, 1);
ret = pTrans->execute(et, ao);
pTrans->close();
printf("%d ", ret);
hugoTrans.clearTable(pNdb);
hugoTrans.loadTable(pNdb, 1);
pTrans = pNdb->startTransaction();
op_row(pTrans, hugoOps, pTab, op1, 0);
op_row(pTrans, hugoOps, pTab, op2, 1);
ret = pTrans->execute(et, ao);
pTrans->close();
printf("%d\n", ret);
hugoTrans.clearTable(pNdb);
hugoTrans.clearTable(pNdb);
}
}
}
return NDBT_OK;
}
template class Vector<NdbScanOperation*>; template class Vector<NdbScanOperation*>;
...@@ -1343,6 +1611,12 @@ TESTCASE("Scan_4006", ...@@ -1343,6 +1611,12 @@ TESTCASE("Scan_4006",
INITIALIZER(runScan_4006); INITIALIZER(runScan_4006);
FINALIZER(runClearTable); FINALIZER(runClearTable);
} }
TESTCASE("IgnoreError", ""){
INITIALIZER(createPkIndex);
STEP(runTestIgnoreError);
FINALIZER(runClearTable);
FINALIZER(createPkIndex_Drop);
}
NDBT_TESTSUITE_END(testNdbApi); NDBT_TESTSUITE_END(testNdbApi);
int main(int argc, const char** argv){ int main(int argc, const char** argv){
......
...@@ -458,7 +458,7 @@ HugoOperations::callback(int res, NdbTransaction* pCon) ...@@ -458,7 +458,7 @@ HugoOperations::callback(int res, NdbTransaction* pCon)
int int
HugoOperations::execute_async(Ndb* pNdb, NdbTransaction::ExecType et, HugoOperations::execute_async(Ndb* pNdb, NdbTransaction::ExecType et,
NdbTransaction::AbortOption eao){ NdbOperation::AbortOption eao){
m_async_reply= 0; m_async_reply= 0;
pTrans->executeAsynchPrepare(et, pTrans->executeAsynchPrepare(et,
...@@ -473,7 +473,7 @@ HugoOperations::execute_async(Ndb* pNdb, NdbTransaction::ExecType et, ...@@ -473,7 +473,7 @@ HugoOperations::execute_async(Ndb* pNdb, NdbTransaction::ExecType et,
int int
HugoOperations::execute_async_prepare(Ndb* pNdb, NdbTransaction::ExecType et, HugoOperations::execute_async_prepare(Ndb* pNdb, NdbTransaction::ExecType et,
NdbTransaction::AbortOption eao){ NdbOperation::AbortOption eao){
m_async_reply= 0; m_async_reply= 0;
pTrans->executeAsynchPrepare(et, pTrans->executeAsynchPrepare(et,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment