Commit e697ec1c authored by joreland@mysql.com's avatar joreland@mysql.com

bug#11133 - ndb

  incorrect handling of writeTuple with multi op transaction
parent 61638019
...@@ -1589,7 +1589,7 @@ void Dbacc::initOpRec(Signal* signal) ...@@ -1589,7 +1589,7 @@ void Dbacc::initOpRec(Signal* signal)
void Dbacc::sendAcckeyconf(Signal* signal) void Dbacc::sendAcckeyconf(Signal* signal)
{ {
signal->theData[0] = operationRecPtr.p->userptr; 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[2] = operationRecPtr.p->fid;
signal->theData[3] = operationRecPtr.p->localdata[0]; signal->theData[3] = operationRecPtr.p->localdata[0];
signal->theData[4] = operationRecPtr.p->localdata[1]; signal->theData[4] = operationRecPtr.p->localdata[1];
...@@ -1671,6 +1671,11 @@ void Dbacc::execACCKEYREQ(Signal* signal) ...@@ -1671,6 +1671,11 @@ void Dbacc::execACCKEYREQ(Signal* signal)
case ZWRITE: case ZWRITE:
case ZSCAN_OP: case ZSCAN_OP:
if (!tgeLocked){ if (!tgeLocked){
if(operationRecPtr.p->operation == ZWRITE)
{
jam();
operationRecPtr.p->operation = ZUPDATE;
}
sendAcckeyconf(signal); sendAcckeyconf(signal);
if (operationRecPtr.p->dirtyRead == ZFALSE) { if (operationRecPtr.p->dirtyRead == ZFALSE) {
/*---------------------------------------------------------------*/ /*---------------------------------------------------------------*/
...@@ -2182,6 +2187,12 @@ Uint32 Dbacc::placeWriteInLockQueue(Signal* signal) ...@@ -2182,6 +2187,12 @@ Uint32 Dbacc::placeWriteInLockQueue(Signal* signal)
return ZWRITE_ERROR; return ZWRITE_ERROR;
}//if }//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[0] = queOperPtr.p->localdata[0];
operationRecPtr.p->localdata[1] = queOperPtr.p->localdata[1]; operationRecPtr.p->localdata[1] = queOperPtr.p->localdata[1];
operationRecPtr.p->prevParallelQue = mlpqOperPtr.i; operationRecPtr.p->prevParallelQue = mlpqOperPtr.i;
......
...@@ -3897,20 +3897,21 @@ void Dblqh::execACCKEYCONF(Signal* signal) ...@@ -3897,20 +3897,21 @@ void Dblqh::execACCKEYCONF(Signal* signal)
* EITHER TO THE TC BLOCK OR DIRECTLY TO THE APPLICATION. THE SCHEMA VERSION * 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 * IS NEEDED SINCE TWO SCHEMA VERSIONS CAN BE ACTIVE SIMULTANEOUSLY ON A
* TABLE. * TABLE.
* ------------------------------------------------------------------------ */ * ----------------------------------------------------------------------- */
if (regTcPtr->operation == ZWRITE) { if (regTcPtr->operation == ZWRITE)
if (signal->theData[1] > 0) { {
/* -------------------------------------------------------------------- Uint32 op= signal->theData[1];
* ACC did perform an insert and thus we should indicate that the WRITE if(likely(op == ZINSERT || op == ZUPDATE))
* is an INSERT otherwise it is an UPDATE. {
* -------------------------------------------------------------------- */ regTcPtr->operation = op;
jam(); }
regTcPtr->operation = ZINSERT; else
} else { {
jam(); warningEvent("Convering %d to ZUPDATE", op);
tcConnectptr.p->operation = ZUPDATE; regTcPtr->operation = ZUPDATE;
}//if }
}//if }//if
ndbrequire(localKeyFlag == 1); ndbrequire(localKeyFlag == 1);
localKey2 = localKey1 & MAX_TUPLES_PER_PAGE; localKey2 = localKey1 & MAX_TUPLES_PER_PAGE;
localKey1 = localKey1 >> MAX_TUPLES_BITS; localKey1 = localKey1 >> MAX_TUPLES_BITS;
......
...@@ -1049,6 +1049,239 @@ int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -1049,6 +1049,239 @@ int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){
return result; 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); NDBT_TESTSUITE(testNdbApi);
TESTCASE("MaxNdb", TESTCASE("MaxNdb",
...@@ -1124,6 +1357,12 @@ TESTCASE("ReadWithoutGetValue", ...@@ -1124,6 +1357,12 @@ TESTCASE("ReadWithoutGetValue",
INITIALIZER(runReadWithoutGetValue); INITIALIZER(runReadWithoutGetValue);
FINALIZER(runClearTable); FINALIZER(runClearTable);
} }
TESTCASE("Bug_11133",
"Test ReadEx-Delete-Write\n"){
INITIALIZER(runLoadTable);
INITIALIZER(runBug_11133);
FINALIZER(runClearTable);
}
NDBT_TESTSUITE_END(testNdbApi); NDBT_TESTSUITE_END(testNdbApi);
int main(int argc, const char** argv){ int main(int argc, const char** argv){
......
...@@ -546,6 +546,10 @@ max-time: 500 ...@@ -546,6 +546,10 @@ max-time: 500
cmd: testNdbApi cmd: testNdbApi
args: -n ReadWithoutGetValue args: -n ReadWithoutGetValue
max-time: 500
cmd: testNdbApi
args: -n Bug_11133 T1
#max-time: 500 #max-time: 500
#cmd: testInterpreter #cmd: testInterpreter
#args: T1 #args: T1
......
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