From: Pekka Nousiainen Date: December 21 2009 3:36pm Subject: bzr commit into mysql-5.1-telco-6.2 branch (pekka:3067) Bug#34348 List-Archive: http://lists.mysql.com/commits/95269 X-Bug: 34348 Message-Id: <20091221153611.90D5523F10@sama.localdomain> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_ZnFYwNOAVPm0boTYoO/8iw)" --Boundary_(ID_ZnFYwNOAVPm0boTYoO/8iw) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline #At file:///export/space/pekka/ndb/version/my51-bug34348/ based on revid:jonas@stripped 3067 Pekka Nousiainen 2009-12-21 bug#34348 01_acc.diff In ACC, hash expand fails if fragment top level directory is full (256). Instead of crash, set a flag on fragment and return error on any insert. The flag is cleared when a hash shrink takes place. modified: storage/ndb/src/kernel/blocks/ERROR_codes.txt storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp storage/ndb/src/ndbapi/ndberror.c storage/ndb/test/include/HugoOperations.hpp storage/ndb/test/ndbapi/testBasic.cpp storage/ndb/test/src/HugoOperations.cpp === modified file 'storage/ndb/src/kernel/blocks/ERROR_codes.txt' --- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt 2009-10-26 20:02:17 +0000 +++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt 2009-12-21 15:35:52 +0000 @@ -601,3 +601,9 @@ LGMAN: TSMAN: ----- 16000: Fail to create data file + +ACC bug#34348 +------------- +3002: limit frags to 2 directory pages (instead of 256) + print (if VM_TRACE) LH variables at expand and shrink + apply before mass data load, reset with error insert 0 === modified file 'storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp' --- a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp 2009-05-26 18:53:34 +0000 +++ b/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp 2009-12-21 15:35:52 +0000 @@ -1,3 +1,4 @@ +/** **/ /* Copyright (C) 2003 MySQL AB All rights reserved. Use is subject to license terms. @@ -180,6 +181,7 @@ ndbout << "Ptr: " << ptr.p->word32 << " #define ZWRITE_ERROR 630 #define ZTO_OP_STATE_ERROR 631 #define ZTOO_EARLY_ACCESS_ERROR 632 +#define ZDIR_RANGE_FULL_ERROR 633 // on fragment #endif class ElementHeader { @@ -472,6 +474,11 @@ struct Fragmentrec { // flag to avoid accessing table record if no char attributes //----------------------------------------------------------------------------- Uint8 hasCharAttr; + +//----------------------------------------------------------------------------- +// flag to mark that execEXPANDCHECK2 has failed due to DirRange full +//----------------------------------------------------------------------------- + Uint8 dirRangeFull; }; typedef Ptr FragmentrecPtr; @@ -849,6 +856,12 @@ private: void initData(); void initRecords(); +#ifdef VM_TRACE + void debug_lh_vars(const char* where); +#else + void debug_lh_vars(const char* where) {} +#endif + // Variables /* --------------------------------------------------------------------------------- */ /* DIRECTORY RANGE */ === modified file 'storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp' --- a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp 2009-09-22 13:04:32 +0000 +++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp 2009-12-21 15:35:52 +0000 @@ -1553,6 +1553,12 @@ void Dbacc::insertExistElemLab(Signal* s /* --------------------------------------------------------------------------------- */ void Dbacc::insertelementLab(Signal* signal) { + if (unlikely(fragrecptr.p->dirRangeFull)) + { + jam(); + acckeyref1Lab(signal, ZDIR_RANGE_FULL_ERROR); + return; + } if (fragrecptr.p->firstOverflowRec == RNIL) { jam(); allocOverflowPage(signal); @@ -5218,6 +5224,12 @@ void Dbacc::execEXPANDCHECK2(Signal* sig /* THE SLACK HAS IMPROVED AND IS NOW ACCEPTABLE AND WE */ /* CAN FORGET ABOUT THE EXPAND PROCESS. */ /*--------------------------------------------------------------*/ + if (ERROR_INSERTED(3002)) + debug_lh_vars("SLK"); + if (fragrecptr.p->dirRangeFull == ZTRUE) { + jam(); + fragrecptr.p->dirRangeFull = ZFALSE; + } return; }//if if (fragrecptr.p->firstOverflowRec == RNIL) { @@ -5265,7 +5277,20 @@ void Dbacc::execEXPANDCHECK2(Signal* sig ptrNull(newDirptr); texpDirRangeIndex = texpDirInd >> 8; ptrCheckGuard(expDirRangePtr, cdirrangesize, dirRange); - arrGuard(texpDirRangeIndex, 256); + Uint32 max_dir_range_size = 256; + if (ERROR_INSERTED(3002)) { + debug_lh_vars("EXP"); + max_dir_range_size = 2; + } + if (texpDirRangeIndex >= max_dir_range_size) { + jam(); + ndbrequire(texpDirRangeIndex == max_dir_range_size); + if (fragrecptr.p->dirRangeFull == ZFALSE) { + jam(); + fragrecptr.p->dirRangeFull = ZTRUE; + } + return; + } expDirptr.i = expDirRangePtr.p->dirArray[texpDirRangeIndex]; if (expDirptr.i == RNIL) { jam(); @@ -5802,6 +5827,13 @@ void Dbacc::execSHRINKCHECK2(Signal* sig jam(); fragrecptr.p->p--; }//if + + if (ERROR_INSERTED(3002)) + debug_lh_vars("SHR"); + if (fragrecptr.p->dirRangeFull == ZTRUE) { + jam(); + fragrecptr.p->dirRangeFull = ZFALSE; + } /*--------------------------------------------------------------------------*/ /* WE START BY FINDING THE NECESSARY INFORMATION OF THE BUCKET TO BE */ @@ -6192,6 +6224,7 @@ void Dbacc::initFragGeneral(FragmentrecP regFragPtr.p->activeDataPage = 0; regFragPtr.p->hasCharAttr = ZFALSE; + regFragPtr.p->dirRangeFull = ZFALSE; regFragPtr.p->nextAllocPage = 0; regFragPtr.p->fragState = FREEFRAG; }//Dbacc::initFragGeneral() @@ -8502,3 +8535,25 @@ Dbacc::execREAD_PSEUDO_REQ(Signal* signa // signal->theData[0] = src[0]; // signal->theData[1] = src[1]; } + +#ifdef VM_TRACE +void +Dbacc::debug_lh_vars(const char* where) +{ + Uint32 b = fragrecptr.p->maxp + fragrecptr.p->p; + Uint32 di = b >> fragrecptr.p->k; + Uint32 ri = di >> 8; + ndbout + << "DBACC: " << where << ":" + << " frag:" << fragrecptr.p->myTableId + << "/" << fragrecptr.p->myfid + << " slack:" << (Int32)fragrecptr.p->slack + << "/" << fragrecptr.p->slackCheck + << " maxp:" << fragrecptr.p->maxp + << " p:" << fragrecptr.p->p + << " di:" << di + << " ri:" << ri + << " full:" << fragrecptr.p->dirRangeFull + << "\n"; +} +#endif === modified file 'storage/ndb/src/ndbapi/ndberror.c' --- a/storage/ndb/src/ndbapi/ndberror.c 2009-10-01 22:18:31 +0000 +++ b/storage/ndb/src/ndbapi/ndberror.c 2009-12-21 15:35:52 +0000 @@ -202,6 +202,7 @@ ErrorBundle ErrorCodes[] = { { 623, HA_ERR_RECORD_FILE_FULL, IS, "623" }, { 624, HA_ERR_RECORD_FILE_FULL, IS, "624" }, { 625, HA_ERR_INDEX_FILE_FULL, IS, "Out of memory in Ndb Kernel, hash index part (increase IndexMemory)" }, + { 633, HA_ERR_INDEX_FILE_FULL, IS, "Table fragment hash index has reached maximum possible size" }, { 640, DMEC, IS, "Too many hash indexes (should not happen)" }, { 826, HA_ERR_RECORD_FILE_FULL, IS, "Too many tables and attributes (increase MaxNoOfAttributes or MaxNoOfTables)" }, { 827, HA_ERR_RECORD_FILE_FULL, IS, "Out of memory in Ndb Kernel, table data (increase DataMemory)" }, === modified file 'storage/ndb/test/include/HugoOperations.hpp' --- a/storage/ndb/test/include/HugoOperations.hpp 2009-05-26 18:53:34 +0000 +++ b/storage/ndb/test/include/HugoOperations.hpp 2009-12-21 15:35:52 +0000 @@ -124,6 +124,9 @@ public: int wait_async(Ndb*, int timeout = -1); + const NdbError& getNdbError() const; + void setQuiet() { m_quiet = true; } + protected: void allocRows(int rows); void deallocRows(); @@ -142,6 +145,10 @@ protected: int m_async_return; friend void HugoOperations_async_callback(int, NdbTransaction*, void*); void callback(int res, NdbTransaction*); + + void setNdbError(const NdbError& error); + NdbError m_error; + bool m_quiet; }; #endif === modified file 'storage/ndb/test/ndbapi/testBasic.cpp' --- a/storage/ndb/test/ndbapi/testBasic.cpp 2009-10-20 12:44:56 +0000 +++ b/storage/ndb/test/ndbapi/testBasic.cpp 2009-12-21 15:35:52 +0000 @@ -21,6 +21,8 @@ #include #include #include +#include +#include #define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb() @@ -1658,6 +1660,234 @@ runDDInsertFailUpdateBatch(NDBT_Context* return result; } +// Bug34348 + +#define chk1(b) \ + if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " << __LINE__ << endl; result = NDBT_FAILED; continue; } +#define chk2(b, e) \ + if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " << __LINE__ << ": " << e << endl; result = NDBT_FAILED; continue; } + +const char* tabname_bug34348 = "TBug34348"; + +int +runBug34348insert(NDBT_Context* ctx, NDBT_Step* step, + HugoOperations& ops, int i, bool* rangeFull) +{ + const int rangeFullError = 633; + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + while (result == NDBT_OK) + { + int code = 0; + chk2(ops.startTransaction(pNdb) == 0, ops.getNdbError()); + chk2(ops.pkInsertRecord(pNdb, i, 1) == 0, ops.getNdbError()); + chk2(ops.execute_Commit(pNdb) == 0 || (code = ops.getNdbError().code) == rangeFullError, ops.getNdbError()); + ops.closeTransaction(pNdb); + *rangeFull = (code == rangeFullError); + break; + } + return result; +} + +int +runBug34348delete(NDBT_Context* ctx, NDBT_Step* step, + HugoOperations& ops, int i) +{ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + while (result == NDBT_OK) + { + chk2(ops.startTransaction(pNdb) == 0, ops.getNdbError()); + chk2(ops.pkDeleteRecord(pNdb, i, 1) == 0, ops.getNdbError()); + chk2(ops.execute_Commit(pNdb) == 0, ops.getNdbError()); + ops.closeTransaction(pNdb); + break; + } + return result; +} + +int +runBug34348(NDBT_Context* ctx, NDBT_Step* step) +{ + myRandom48Init(NdbTick_CurrentMillisecond()); + Ndb* pNdb = GETNDB(step); + NdbDictionary::Dictionary* pDict = pNdb->getDictionary(); + NdbRestarter restarter; + int result = NDBT_OK; + const int loops = ctx->getNumLoops(); + const int errInsDBACC = 3002; + const int errInsCLEAR = 0; + Uint32* rowmask = 0; + + while (result == NDBT_OK) + { + chk1(restarter.insertErrorInAllNodes(errInsDBACC) == 0); + ndbout << "error insert " << errInsDBACC << " done" << endl; + + const NdbDictionary::Table* pTab = 0; + while (result == NDBT_OK) + { + (void)pDict->dropTable(tabname_bug34348); + NdbDictionary::Table tab(tabname_bug34348); + { + NdbDictionary::Column col("a"); + col.setType(NdbDictionary::Column::Unsigned); + col.setPrimaryKey(true); + tab.addColumn(col); + } + { + NdbDictionary::Column col("b"); + col.setType(NdbDictionary::Column::Unsigned); + col.setNullable(false); + tab.addColumn(col); + } + chk2(pDict->createTable(tab) == 0, pDict->getNdbError()); + chk2((pTab = pDict->getTable(tabname_bug34348)) != 0, pDict->getNdbError()); + break; + } + + HugoOperations ops(*pTab); + ops.setQuiet(); + + int rowmaxprev = 0; + int loop = 0; + while (result == NDBT_OK && loop < loops) + { + ndbout << "loop:" << loop << endl; + int rowcnt = 0; + + // fill up + while (result == NDBT_OK) + { + bool rangeFull; + chk1(runBug34348insert(ctx, step, ops, rowcnt, &rangeFull) == NDBT_OK); + if (rangeFull) + { + // 360449 (1 fragment) + ndbout << "dir range full at " << rowcnt << endl; + break; + } + rowcnt++; + } + chk1(result == NDBT_OK); + const int rowmax = rowcnt; + + if (loop == 0) + rowmaxprev = rowmax; + else + chk2(rowmaxprev == rowmax, "rowmaxprev:" << rowmaxprev << " rowmax:" << rowmax); + + const int sz = (rowmax + 31) / 32; + delete [] rowmask; + rowmask = new Uint32 [sz]; + BitmaskImpl::clear(sz, rowmask); + { + int i; + for (i = 0; i < rowmax; i++) + BitmaskImpl::set(sz, rowmask, i); + } + + // random delete until insert succeeds + while (result == NDBT_OK) + { + int i = myRandom48(rowmax); + if (!BitmaskImpl::get(sz, rowmask, i)) + continue; + chk1(runBug34348delete(ctx, step, ops, i) == NDBT_OK); + BitmaskImpl::clear(sz, rowmask, i); + rowcnt--; + bool rangeFull; + chk1(runBug34348insert(ctx, step, ops, rowmax, &rangeFull) == NDBT_OK); + if (!rangeFull) + { + chk1(runBug34348delete(ctx, step, ops, rowmax) == NDBT_OK); + // 344063 (1 fragment) + ndbout << "dir range released at " << rowcnt << endl; + break; + } + } + chk1(result == NDBT_OK); + assert(BitmaskImpl::count(sz, rowmask)== rowcnt); + + // delete about 1/2 remaining + while (result == NDBT_OK) + { + int i; + for (i = 0; result == NDBT_OK && i < rowmax; i++) + { + if (!BitmaskImpl::get(sz, rowmask, i)) + continue; + if (myRandom48(100) < 50) + continue; + chk1(runBug34348delete(ctx, step, ops, i) == NDBT_OK); + BitmaskImpl::clear(sz, rowmask, i); + rowcnt--; + } + ndbout << "deleted down to " << rowcnt << endl; + break; + } + chk1(result == NDBT_OK); + assert(BitmaskImpl::count(sz, rowmask)== rowcnt); + + // insert until full again + while (result == NDBT_OK) + { + int i; + for (i = 0; result == NDBT_OK && i < rowmax; i++) + { + if (BitmaskImpl::get(sz, rowmask, i)) + continue; + bool rangeFull; + chk1(runBug34348insert(ctx, step, ops, i, &rangeFull) == NDBT_OK); + // assume all can be inserted back + chk2(!rangeFull, "dir range full too early at " << rowcnt); + BitmaskImpl::set(sz, rowmask, i); + rowcnt++; + } + chk1(result == NDBT_OK); + ndbout << "inserted all back to " << rowcnt << endl; + break; + } + chk1(result == NDBT_OK); + assert(BitmaskImpl::count(sz, rowmask)== rowcnt); + + // delete all + while (result == NDBT_OK) + { + int i; + for (i = 0; result == NDBT_OK && i < rowmax; i++) + { + if (!BitmaskImpl::get(sz, rowmask, i)) + continue; + chk1(runBug34348delete(ctx, step, ops, i) == NDBT_OK); + BitmaskImpl::clear(sz, rowmask, i); + rowcnt--; + } + ndbout << "deleted all" << endl; + break; + } + chk1(result == NDBT_OK); + assert(BitmaskImpl::count(sz, rowmask)== rowcnt); + assert(rowcnt == 0); + + loop++; + } + + chk2(pDict->dropTable(tabname_bug34348) == 0, pDict->getNdbError()); + + chk1(restarter.insertErrorInAllNodes(errInsCLEAR) == 0); + ndbout << "error insert clear done" << endl; + break; + } + + if (result != NDBT_OK && restarter.insertErrorInAllNodes(errInsCLEAR) != 0) + g_err << "error insert clear failed" << endl; + + delete [] rowmask; + rowmask = 0; + return result; +} + template class Vector; NDBT_TESTSUITE(testBasic); @@ -1959,6 +2189,12 @@ TESTCASE("DDInsertFailUpdateBatch", "Verify DD insert failure effect on other ops in batch on same PK"){ STEP(runDDInsertFailUpdateBatch); } + +TESTCASE("Bug34348", + "Test fragment directory range full in ACC.\n" + "NOTE: If interrupted, must clear error insert 3002 manually"){ + STEP(runBug34348); +} NDBT_TESTSUITE_END(testBasic); #if 0 === modified file 'storage/ndb/test/src/HugoOperations.cpp' --- a/storage/ndb/test/src/HugoOperations.cpp 2009-05-26 18:53:34 +0000 +++ b/storage/ndb/test/src/HugoOperations.cpp 2009-12-21 15:35:52 +0000 @@ -18,6 +18,13 @@ #include +#undef ERR +#define ERR(error) \ +{ \ + const NdbError &_error= (error); \ + if (!m_quiet) ERR_OUT(g_err, _error); \ +} + int HugoOperations::startTransaction(Ndb* pNdb, const NdbDictionary::Table *table, const char *keyData, Uint32 keyLen){ @@ -30,6 +37,7 @@ int HugoOperations::startTransaction(Ndb if (pTrans == NULL) { const NdbError err = pNdb->getNdbError(); ERR(err); + setNdbError(err); return NDBT_FAILED; } return NDBT_OK; @@ -90,6 +98,7 @@ int HugoOperations::pkReadRecord(Ndb* pN } if (pOp == NULL) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -119,6 +128,7 @@ rand_lock_mode: if( check == -1 ) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -141,6 +151,7 @@ rand_lock_mode: if((rows[r]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } } @@ -174,6 +185,7 @@ int HugoOperations::pkReadRandRecord(Ndb } if (pOp == NULL) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -203,6 +215,7 @@ rand_lock_mode: if( check == -1 ) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -220,6 +233,7 @@ rand_lock_mode: if((rows[r]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } } @@ -242,12 +256,14 @@ int HugoOperations::pkUpdateRecord(Ndb* NdbOperation* pOp = getOperation(pTrans, NdbOperation::UpdateRequest); if (pOp == NULL) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->updateTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -271,6 +287,7 @@ HugoOperations::setValues(NdbOperation* if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pOp, a, rowId, updateId ) != 0){ ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } } @@ -289,17 +306,20 @@ int HugoOperations::pkInsertRecord(Ndb* NdbOperation* pOp = getOperation(pTrans, NdbOperation::InsertRequest); if (pOp == NULL) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->insertTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } if(setValues(pOp, r+recordNo, updatesValue) != NDBT_OK) { + m_error.code = pTrans->getNdbError().code; return NDBT_FAILED; } } @@ -316,12 +336,14 @@ int HugoOperations::pkWriteRecord(Ndb* p NdbOperation* pOp = pTrans->getNdbOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->writeTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -334,6 +356,7 @@ int HugoOperations::pkWriteRecord(Ndb* p if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } } @@ -351,12 +374,14 @@ int HugoOperations::pkWritePartialRecord NdbOperation* pOp = pTrans->getNdbOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->writeTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -376,12 +401,14 @@ int HugoOperations::pkDeleteRecord(Ndb* NdbOperation* pOp = getOperation(pTrans, NdbOperation::DeleteRequest); if (pOp == NULL) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->deleteTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -401,10 +428,12 @@ int HugoOperations::execute_Commit(Ndb* const NdbError err = pTrans->getNdbError(); if( check == -1 || err.code) { ERR(err); + setNdbError(err); NdbOperation* pOp = pTrans->getNdbErrorOperation(); if (pOp != NULL){ const NdbError err2 = pOp->getNdbError(); ERR(err2); + setNdbError(err2); } if (err.code == 0) return NDBT_FAILED; @@ -423,6 +452,7 @@ int HugoOperations::execute_Commit(Ndb* case -1: const NdbError err = pTrans->getNdbError(); ERR(err); + setNdbError(err); return (err.code > 0 ? err.code : NDBT_FAILED); } @@ -450,12 +480,16 @@ int HugoOperations::execute_NoCommit(Ndb const NdbError err = pTrans->getNdbError(); if( check == -1 || err.code) { ERR(err); + setNdbError(err); const NdbOperation* pOp = pTrans->getNdbErrorOperation(); while (pOp != NULL) { const NdbError err2 = pOp->getNdbError(); if (err2.code) + { ERR(err2); + setNdbError(err2); + } pOp = pTrans->getNextCompletedOperation(pOp); } if (err.code == 0) @@ -475,6 +509,7 @@ int HugoOperations::execute_NoCommit(Ndb case -1: const NdbError err = pTrans->getNdbError(); ERR(err); + setNdbError(err); return (err.code > 0 ? err.code : NDBT_FAILED); } @@ -500,6 +535,7 @@ int HugoOperations::execute_Rollback(Ndb if( check == -1 ) { const NdbError err = pTrans->getNdbError(); ERR(err); + setNdbError(err); return NDBT_FAILED; } return NDBT_OK; @@ -576,7 +612,8 @@ HugoOperations::wait_async(Ndb* pNdb, in HugoOperations::HugoOperations(const NdbDictionary::Table& _tab, const NdbDictionary::Index* idx): UtilTransactions(_tab, idx), - calc(_tab) + calc(_tab), + m_quiet(false) { } @@ -599,6 +636,7 @@ HugoOperations::equalForRow(NdbOperation if(equalForAttr(pOp, a, row) != 0) { ERR(pOp->getNdbError()); + setNdbError(pOp->getNdbError()); return NDBT_FAILED; } } @@ -750,6 +788,7 @@ int HugoOperations::indexReadRecords(Ndb NdbOperation* pOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -759,6 +798,7 @@ int HugoOperations::indexReadRecords(Ndb check = pOp->readTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -771,6 +811,7 @@ int HugoOperations::indexReadRecords(Ndb if((rows[r]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } } @@ -791,12 +832,14 @@ HugoOperations::indexUpdateRecord(Ndb*, NdbOperation* pOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } check = pOp->updateTuple(); if( check == -1 ) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } @@ -809,6 +852,7 @@ HugoOperations::indexUpdateRecord(Ndb*, if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } } @@ -835,6 +879,7 @@ HugoOperations::scanReadRecords(Ndb* pNd if((rows[0]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); + setNdbError(pTrans->getNdbError()); return NDBT_FAILED; } } @@ -845,4 +890,26 @@ HugoOperations::scanReadRecords(Ndb* pNd return 0; } +static void +update(const NdbError & _err) +{ + NdbError & error = (NdbError &) _err; + ndberror_struct ndberror = (ndberror_struct)error; + ndberror_update(&ndberror); + error = NdbError(ndberror); +} + +const NdbError & +HugoOperations::getNdbError() const +{ + update(m_error); + return m_error; +} + +void +HugoOperations::setNdbError(const NdbError& error) +{ + m_error.code = error.code ? error.code : 1; +} + template class Vector; --Boundary_(ID_ZnFYwNOAVPm0boTYoO/8iw) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name="bzr/pekka@stripped" Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/pekka@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: pekka@stripped # target_branch: file:///export/space/pekka/ndb/version/my51-bug34348/ # testament_sha1: 4d45e82ea353cc77dc9a2d8368bb1efa1bd45cef # timestamp: 2009-12-21 17:36:11 +0200 # base_revision_id: jonas@stripped # # Begin bundle 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 wA== --Boundary_(ID_ZnFYwNOAVPm0boTYoO/8iw)--