summaryrefslogtreecommitdiff
path: root/ndb
diff options
context:
space:
mode:
authormskold/marty@mysql.com/quadfish.(none) <>2007-12-06 17:15:21 +0100
committermskold/marty@mysql.com/quadfish.(none) <>2007-12-06 17:15:21 +0100
commit27c025061d8bd3478ea4bd2512dbf2e4ca0c56db (patch)
treeaa4869373d31aa5f1ecf96103d3d79d859b6d901 /ndb
parent88fc48fd5e342a7ad8cc6ac15a9dbe7c508fb019 (diff)
downloadmariadb-git-27c025061d8bd3478ea4bd2512dbf2e4ca0c56db.tar.gz
bug#21072 Duplicate key error in NDB references wrong key: Return correct key for non-batching inserts
Diffstat (limited to 'ndb')
-rw-r--r--ndb/include/kernel/signaldata/TcKeyRef.hpp3
-rw-r--r--ndb/include/kernel/signaldata/TcRollbackRep.hpp3
-rw-r--r--ndb/include/ndbapi/NdbDictionary.hpp7
-rw-r--r--ndb/src/kernel/blocks/dbtc/Dbtc.hpp1
-rw-r--r--ndb/src/kernel/blocks/dbtc/DbtcMain.cpp21
-rw-r--r--ndb/src/ndbapi/NdbDictionary.cpp9
-rw-r--r--ndb/src/ndbapi/NdbOperationExec.cpp7
-rw-r--r--ndb/src/ndbapi/NdbTransaction.cpp13
-rw-r--r--ndb/src/ndbapi/ndberror.c2
9 files changed, 58 insertions, 8 deletions
diff --git a/ndb/include/kernel/signaldata/TcKeyRef.hpp b/ndb/include/kernel/signaldata/TcKeyRef.hpp
index 2846ce3854f..56f6cdae29d 100644
--- a/ndb/include/kernel/signaldata/TcKeyRef.hpp
+++ b/ndb/include/kernel/signaldata/TcKeyRef.hpp
@@ -40,12 +40,13 @@ class TcKeyRef {
friend bool printTCKEYREF(FILE *, const Uint32 *, Uint32, Uint16);
public:
- STATIC_CONST( SignalLength = 4 );
+ STATIC_CONST( SignalLength = 5 );
private:
Uint32 connectPtr;
Uint32 transId[2];
Uint32 errorCode;
+ Uint32 errorData;
};
#endif
diff --git a/ndb/include/kernel/signaldata/TcRollbackRep.hpp b/ndb/include/kernel/signaldata/TcRollbackRep.hpp
index 3b5e2f3d3cb..609756605d5 100644
--- a/ndb/include/kernel/signaldata/TcRollbackRep.hpp
+++ b/ndb/include/kernel/signaldata/TcRollbackRep.hpp
@@ -38,12 +38,13 @@ class TcRollbackRep {
friend bool printTCROLBACKREP(FILE *, const Uint32 *, Uint32, Uint16);
public:
- STATIC_CONST( SignalLength = 4 );
+ STATIC_CONST( SignalLength = 5 );
private:
Uint32 connectPtr;
Uint32 transId[2];
Uint32 returnCode;
+ Uint32 errorData;
};
#endif
diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp
index 445bb513ffc..24fb9811b3d 100644
--- a/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/ndb/include/ndbapi/NdbDictionary.hpp
@@ -792,7 +792,12 @@ public:
* Get the name of the table being indexed
*/
const char * getTable() const;
-
+
+ /**
+ * Get the table representing the index
+ */
+ const Table * getIndexTable() const;
+
/**
* Get the number of columns in the index
*/
diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
index 710d2fde182..6fb03fa2407 100644
--- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
+++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
@@ -727,6 +727,7 @@ public:
// Index op return context
UintR indexOp;
UintR clientData;
+ Uint32 errorData;
UintR attrInfoLen;
UintR accumulatingIndexOp;
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index 91adae183f4..57daffbf331 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -5107,6 +5107,7 @@ void Dbtc::releaseDirtyWrite(Signal* signal)
void Dbtc::execLQHKEYREF(Signal* signal)
{
const LqhKeyRef * const lqhKeyRef = (LqhKeyRef *)signal->getDataPtr();
+ Uint32 indexId = 0;
jamEntry();
UintR compare_transid1, compare_transid2;
@@ -5158,6 +5159,10 @@ void Dbtc::execLQHKEYREF(Signal* signal)
ptrCheckGuard(opPtr, ctcConnectFilesize, localTcConnectRecord);
// The operation executed an index trigger
+ TcIndexData* indexData = c_theIndexes.getPtr(currentIndexId);
+ indexId = indexData->indexId;
+ regApiPtr->errorData = indexId;
+ ndbout_c("LQHKEYREF, found index %u", indexId);
const Uint32 opType = regTcPtr->operation;
if (errCode == ZALREADYEXIST)
errCode = terrorCode = ZNOTUNIQUE;
@@ -5170,7 +5175,6 @@ void Dbtc::execLQHKEYREF(Signal* signal)
} else {
jam();
/** ZDELETE && NOT_FOUND */
- TcIndexData* indexData = c_theIndexes.getPtr(currentIndexId);
if(indexData->indexState == IS_BUILDING && state != CS_ABORTING){
jam();
/**
@@ -5242,12 +5246,16 @@ void Dbtc::execLQHKEYREF(Signal* signal)
jam();
regApiPtr->lqhkeyreqrec--; // Compensate for extra during read
tcKeyRef->connectPtr = indexOp;
+ ndbout_c("TCKEYREF, sending index %u", indexId);
+ tcKeyRef->errorData = indexId;
EXECUTE_DIRECT(DBTC, GSN_TCKEYREF, signal, TcKeyRef::SignalLength);
apiConnectptr.i = save;
apiConnectptr.p = regApiPtr;
} else {
jam();
tcKeyRef->connectPtr = clientData;
+ ndbout_c("TCKEYREF, sending index %u", indexId);
+ tcKeyRef->errorData = indexId;
sendSignal(regApiPtr->ndbapiBlockref,
GSN_TCKEYREF, signal, TcKeyRef::SignalLength, JBB);
}//if
@@ -10548,6 +10556,7 @@ void Dbtc::releaseAbortResources(Signal* signal)
tcRollbackRep->transId[0] = apiConnectptr.p->transid[0];
tcRollbackRep->transId[1] = apiConnectptr.p->transid[1];
tcRollbackRep->returnCode = apiConnectptr.p->returncode;
+ tcRollbackRep->errorData = apiConnectptr.p->errorData;
sendSignal(blockRef, GSN_TCROLLBACKREP, signal,
TcRollbackRep::SignalLength, JBB);
}
@@ -11972,6 +11981,7 @@ void Dbtc::execTCKEYCONF(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -11991,6 +12001,7 @@ void Dbtc::execTCKEYCONF(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12074,6 +12085,7 @@ void Dbtc::execTCKEYREF(Signal* signal)
tcIndxRef->transId[0] = tcKeyRef->transId[0];
tcIndxRef->transId[1] = tcKeyRef->transId[1];
tcIndxRef->errorCode = tcKeyRef->errorCode;
+ tcIndxRef->errorData = 0;
releaseIndexOperation(regApiPtr, indexOp);
@@ -12151,6 +12163,7 @@ void Dbtc::execTRANSID_AI(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4000;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12166,6 +12179,7 @@ void Dbtc::execTRANSID_AI(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12194,6 +12208,7 @@ void Dbtc::execTRANSID_AI(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
*/
@@ -12219,6 +12234,7 @@ void Dbtc::execTRANSID_AI(Signal* signal)
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ // tcIndxRef->errorData = ??; Where to find indexId
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12272,6 +12288,7 @@ void Dbtc::readIndexTable(Signal* signal,
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4000;
+ // tcIndxRef->errorData = ??; Where to find indexId
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -12414,6 +12431,7 @@ void Dbtc::executeIndexOperation(Signal* signal,
tcIndxRef->transId[0] = regApiPtr->transid[0];
tcIndxRef->transId[1] = regApiPtr->transid[1];
tcIndxRef->errorCode = 4349;
+ tcIndxRef->errorData = 0;
sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal,
TcKeyRef::SignalLength, JBB);
return;
@@ -13012,6 +13030,7 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
}
regApiPtr->currSavePointId = currSavePointId;
+ ndbout_c("TCKEYREQ, saving index %u", indexData->indexId);
tcConnectptr.p->currentIndexId = indexData->indexId;
// *********** KEYINFO ***********
diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp
index 86a6624959e..32a2cd8ba0c 100644
--- a/ndb/src/ndbapi/NdbDictionary.cpp
+++ b/ndb/src/ndbapi/NdbDictionary.cpp
@@ -542,6 +542,15 @@ NdbDictionary::Index::getTable() const {
return m_impl.getTable();
}
+const NdbDictionary::Table *
+NdbDictionary::Index::getIndexTable() const {
+ NdbTableImpl * t = m_impl.m_table;
+ if (t) {
+ return t->m_facade;
+ }
+ return 0;
+}
+
unsigned
NdbDictionary::Index::getNoOfColumns() const {
return m_impl.m_columns.size();
diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp
index feff9ed5f36..9a50b000a1a 100644
--- a/ndb/src/ndbapi/NdbOperationExec.cpp
+++ b/ndb/src/ndbapi/NdbOperationExec.cpp
@@ -24,6 +24,7 @@
#include "Interpreter.hpp"
#include <AttributeHeader.hpp>
#include <signaldata/TcKeyReq.hpp>
+#include <signaldata/TcKeyRef.hpp>
#include <signaldata/KeyInfo.hpp>
#include <signaldata/AttrInfo.hpp>
#include <signaldata/ScanTab.hpp>
@@ -550,6 +551,12 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
theNdbCon->theReturnStatus = NdbTransaction::ReturnFailure;
}
theError.code = aSignal->readData(4);
+ if (aSignal->getLength() == TcKeyRef::SignalLength)
+ {
+ // Signal may contain additional error data
+ theError.details = (char *) aSignal->readData(5);
+ }
+
theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), ao);
if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read
diff --git a/ndb/src/ndbapi/NdbTransaction.cpp b/ndb/src/ndbapi/NdbTransaction.cpp
index 1ebc5b7ef24..262deb0050e 100644
--- a/ndb/src/ndbapi/NdbTransaction.cpp
+++ b/ndb/src/ndbapi/NdbTransaction.cpp
@@ -30,6 +30,7 @@
#include <signaldata/TcCommit.hpp>
#include <signaldata/TcKeyFailConf.hpp>
#include <signaldata/TcHbRep.hpp>
+#include <signaldata/TcRollbackRep.hpp>
/*****************************************************************************
NdbTransaction( Ndb* aNdb );
@@ -1757,6 +1758,8 @@ Remark: Handles the reception of the ROLLBACKREP signal.
int
NdbTransaction::receiveTCROLLBACKREP( NdbApiSignal* aSignal)
{
+ DBUG_ENTER("NdbTransaction::receiveTCROLLBACKREP");
+
/****************************************************************************
Check that we are expecting signals from this transaction and that it doesn't
belong to a transaction already completed. Simply ignore messages from other
@@ -1764,6 +1767,12 @@ transactions.
****************************************************************************/
if(checkState_TransId(aSignal->getDataPtr() + 1)){
theError.code = aSignal->readData(4);// Override any previous errors
+ if (aSignal->getLength() == TcRollbackRep::SignalLength)
+ {
+ DBUG_PRINT("info", ("Found error data %u", aSignal->readData(5)));
+ // Signal may contain additional error data
+ theError.details = (char *) aSignal->readData(5);
+ }
/**********************************************************************/
/* A serious error has occured. This could be due to deadlock or */
@@ -1775,14 +1784,14 @@ transactions.
theCompletionStatus = CompletedFailure;
theCommitStatus = Aborted;
theReturnStatus = ReturnFailure;
- return 0;
+ DBUG_RETURN(0);
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
}
- return -1;
+ DBUG_RETURN(-1);
}//NdbTransaction::receiveTCROLLBACKREP()
/*******************************************************************************
diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c
index 56eb2c0f8bd..4c60e384e6c 100644
--- a/ndb/src/ndbapi/ndberror.c
+++ b/ndb/src/ndbapi/ndberror.c
@@ -640,8 +640,6 @@ ndberror_update(ndberror_struct * error){
if(!found){
error->status = ST_U;
}
-
- error->details = 0;
}
int