mirror of
https://github.com/MariaDB/server.git
synced 2026-05-07 15:45:33 +02:00
bug#11133 - ndb
incorrect handling of writeTuple with multi op transaction
ndb/src/kernel/blocks/dbacc/DbaccMain.cpp:
1) Pass operation instead of insertIsDone to LQH
2) transform operation correctly when in parallell que
(multi op within same trans)
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp:
Let ACC decide what operation was performed when WRITE
ndb/test/ndbapi/testNdbApi.cpp:
Add testcase for bug 11133
ndb/test/run-test/daily-basic-tests.txt:
Add testcase for bug 11133
This commit is contained in:
parent
4c30434d15
commit
62321bd298
4 changed files with 269 additions and 14 deletions
|
|
@ -1589,7 +1589,7 @@ void Dbacc::initOpRec(Signal* signal)
|
|||
void Dbacc::sendAcckeyconf(Signal* signal)
|
||||
{
|
||||
signal->theData[0] = operationRecPtr.p->userptr;
|
||||
signal->theData[1] = operationRecPtr.p->insertIsDone;
|
||||
signal->theData[1] = operationRecPtr.p->operation;
|
||||
signal->theData[2] = operationRecPtr.p->fid;
|
||||
signal->theData[3] = operationRecPtr.p->localdata[0];
|
||||
signal->theData[4] = operationRecPtr.p->localdata[1];
|
||||
|
|
@ -1671,6 +1671,11 @@ void Dbacc::execACCKEYREQ(Signal* signal)
|
|||
case ZWRITE:
|
||||
case ZSCAN_OP:
|
||||
if (!tgeLocked){
|
||||
if(operationRecPtr.p->operation == ZWRITE)
|
||||
{
|
||||
jam();
|
||||
operationRecPtr.p->operation = ZUPDATE;
|
||||
}
|
||||
sendAcckeyconf(signal);
|
||||
if (operationRecPtr.p->dirtyRead == ZFALSE) {
|
||||
/*---------------------------------------------------------------*/
|
||||
|
|
@ -2182,6 +2187,12 @@ Uint32 Dbacc::placeWriteInLockQueue(Signal* signal)
|
|||
return ZWRITE_ERROR;
|
||||
}//if
|
||||
|
||||
if(operationRecPtr.p->operation == ZWRITE)
|
||||
{
|
||||
operationRecPtr.p->operation =
|
||||
(mlpqOperPtr.p->operation == ZDELETE) ? ZINSERT : ZUPDATE;
|
||||
}
|
||||
|
||||
operationRecPtr.p->localdata[0] = queOperPtr.p->localdata[0];
|
||||
operationRecPtr.p->localdata[1] = queOperPtr.p->localdata[1];
|
||||
operationRecPtr.p->prevParallelQue = mlpqOperPtr.i;
|
||||
|
|
|
|||
|
|
@ -3897,20 +3897,21 @@ void Dblqh::execACCKEYCONF(Signal* signal)
|
|||
* EITHER TO THE TC BLOCK OR DIRECTLY TO THE APPLICATION. THE SCHEMA VERSION
|
||||
* IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A
|
||||
* TABLE.
|
||||
* ------------------------------------------------------------------------ */
|
||||
if (regTcPtr->operation == ZWRITE) {
|
||||
if (signal->theData[1] > 0) {
|
||||
/* --------------------------------------------------------------------
|
||||
* ACC did perform an insert and thus we should indicate that the WRITE
|
||||
* is an INSERT otherwise it is an UPDATE.
|
||||
* -------------------------------------------------------------------- */
|
||||
jam();
|
||||
regTcPtr->operation = ZINSERT;
|
||||
} else {
|
||||
jam();
|
||||
tcConnectptr.p->operation = ZUPDATE;
|
||||
}//if
|
||||
* ----------------------------------------------------------------------- */
|
||||
if (regTcPtr->operation == ZWRITE)
|
||||
{
|
||||
Uint32 op= signal->theData[1];
|
||||
if(likely(op == ZINSERT || op == ZUPDATE))
|
||||
{
|
||||
regTcPtr->operation = op;
|
||||
}
|
||||
else
|
||||
{
|
||||
warningEvent("Convering %d to ZUPDATE", op);
|
||||
regTcPtr->operation = ZUPDATE;
|
||||
}
|
||||
}//if
|
||||
|
||||
ndbrequire(localKeyFlag == 1);
|
||||
localKey2 = localKey1 & MAX_TUPLES_PER_PAGE;
|
||||
localKey1 = localKey1 >> MAX_TUPLES_BITS;
|
||||
|
|
|
|||
|
|
@ -1049,6 +1049,239 @@ int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){
|
|||
return result;
|
||||
}
|
||||
|
||||
int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
|
||||
int result = NDBT_OK;
|
||||
const NdbDictionary::Table* pTab = ctx->getTab();
|
||||
|
||||
HugoOperations hugoOps(*pTab);
|
||||
|
||||
Ndb* pNdb = GETNDB(step);
|
||||
Uint32 lm;
|
||||
|
||||
NdbConnection* pCon = pNdb->startTransaction();
|
||||
if (pCon == NULL){
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
|
||||
if (pOp == NULL){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (pOp->readTuple(NdbOperation::LM_Exclusive) != 0){
|
||||
pNdb->closeTransaction(pCon);
|
||||
ERR(pOp->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() == true){
|
||||
if(hugoOps.equalForAttr(pOp, a, 1) != 0){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() != true){
|
||||
if (pOp->getValue(pTab->getColumn(a)->getName()) == NULL) {
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int check = pCon->execute(NoCommit);
|
||||
if (check == 0){
|
||||
ndbout << "execute worked" << endl;
|
||||
} else {
|
||||
ERR(pCon->getNdbError());
|
||||
result = NDBT_FAILED;
|
||||
}
|
||||
|
||||
pOp = pCon->getNdbOperation(pTab->getName());
|
||||
if (pOp == NULL){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (pOp->deleteTuple() != 0){
|
||||
pNdb->closeTransaction(pCon);
|
||||
ERR(pOp->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() == true){
|
||||
if(hugoOps.equalForAttr(pOp, a, 1) != 0){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check = pCon->execute(NoCommit);
|
||||
if (check == 0){
|
||||
ndbout << "execute worked" << endl;
|
||||
} else {
|
||||
ERR(pCon->getNdbError());
|
||||
result = NDBT_FAILED;
|
||||
}
|
||||
|
||||
pOp = pCon->getNdbOperation(pTab->getName());
|
||||
if (pOp == NULL){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (pOp->writeTuple() != 0){
|
||||
pNdb->closeTransaction(pCon);
|
||||
ERR(pOp->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() == true){
|
||||
if(hugoOps.equalForAttr(pOp, a, 1) != 0){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() != true){
|
||||
if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0)
|
||||
{
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check = pCon->execute(NoCommit);
|
||||
if (check == 0){
|
||||
ndbout << "execute worked" << endl;
|
||||
} else {
|
||||
ERR(pCon->getNdbError());
|
||||
result = NDBT_FAILED;
|
||||
}
|
||||
|
||||
pOp = pCon->getNdbOperation(pTab->getName());
|
||||
if (pOp == NULL){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (pOp->writeTuple() != 0){
|
||||
pNdb->closeTransaction(pCon);
|
||||
ERR(pOp->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() == true){
|
||||
if(hugoOps.equalForAttr(pOp, a, 1) != 0){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() != true){
|
||||
if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0)
|
||||
{
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check = pCon->execute(NoCommit);
|
||||
if (check == 0){
|
||||
ndbout << "execute worked" << endl;
|
||||
} else {
|
||||
ERR(pCon->getNdbError());
|
||||
result = NDBT_FAILED;
|
||||
}
|
||||
|
||||
check = pCon->execute(Rollback);
|
||||
if (check == 0){
|
||||
ndbout << "execute worked" << endl;
|
||||
} else {
|
||||
ERR(pCon->getNdbError());
|
||||
result = NDBT_FAILED;
|
||||
}
|
||||
|
||||
pCon->close();
|
||||
|
||||
pCon = pNdb->startTransaction();
|
||||
if (pCon == NULL){
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
pOp = pCon->getNdbOperation(pTab->getName());
|
||||
if (pOp == NULL){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (pOp->writeTuple() != 0){
|
||||
pNdb->closeTransaction(pCon);
|
||||
ERR(pOp->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() == true){
|
||||
if(hugoOps.equalForAttr(pOp, a, 1) != 0){
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int a = 0; a<pTab->getNoOfColumns(); a++){
|
||||
if (pTab->getColumn(a)->getPrimaryKey() != true){
|
||||
if(hugoOps.setValueForAttr(pOp, a, 1, 1) != 0)
|
||||
{
|
||||
ERR(pCon->getNdbError());
|
||||
pNdb->closeTransaction(pCon);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
check = pCon->execute(Commit);
|
||||
if (check == 0){
|
||||
ndbout << "execute worked" << endl;
|
||||
} else {
|
||||
ERR(pCon->getNdbError());
|
||||
result = NDBT_FAILED;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NDBT_TESTSUITE(testNdbApi);
|
||||
TESTCASE("MaxNdb",
|
||||
|
|
@ -1124,6 +1357,12 @@ TESTCASE("ReadWithoutGetValue",
|
|||
INITIALIZER(runReadWithoutGetValue);
|
||||
FINALIZER(runClearTable);
|
||||
}
|
||||
TESTCASE("Bug_11133",
|
||||
"Test ReadEx-Delete-Write\n"){
|
||||
INITIALIZER(runLoadTable);
|
||||
INITIALIZER(runBug_11133);
|
||||
FINALIZER(runClearTable);
|
||||
}
|
||||
NDBT_TESTSUITE_END(testNdbApi);
|
||||
|
||||
int main(int argc, const char** argv){
|
||||
|
|
|
|||
|
|
@ -546,6 +546,10 @@ max-time: 500
|
|||
cmd: testNdbApi
|
||||
args: -n ReadWithoutGetValue
|
||||
|
||||
max-time: 500
|
||||
cmd: testNdbApi
|
||||
args: -n Bug_11133 T1
|
||||
|
||||
#max-time: 500
|
||||
#cmd: testInterpreter
|
||||
#args: T1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue