diff options
author | unknown <joreland@mysql.com> | 2004-10-04 12:59:04 +0200 |
---|---|---|
committer | unknown <joreland@mysql.com> | 2004-10-04 12:59:04 +0200 |
commit | 499ebf4d413e38f7f1af7a1bfe4d028a284cd2dd (patch) | |
tree | b750bc7fa2f2ecd3aebcb10d97e56378055b2553 /ndb/src | |
parent | a64953ed3f469e3efdff4dd6462a1756675459b6 (diff) | |
download | mariadb-git-499ebf4d413e38f7f1af7a1bfe4d028a284cd2dd.tar.gz |
NdbIndexScanOperation::reset_bounds()
- Send BOUNDS as KEYINFO
- At restart, only reset KEYINFO
--
Fix resource shortage at KEYINFO in Dbtc and Dblqh w.r.t scan
--
ndb/include/kernel/signaldata/AttrInfo.hpp:
Let NdbScanOperation access AttrInfo
ndb/include/kernel/signaldata/KeyInfo.hpp:
Let NdbScanOperation access AttrInfo
ndb/include/kernel/signaldata/ScanFrag.hpp:
Send KeyLen in ScanFragReq (for range scans)
ndb/include/kernel/signaldata/ScanTab.hpp:
Send KeyLen in ScanTabReq (for range scans)
ndb/include/ndbapi/NdbConnection.hpp:
Function for adding op to list
ndb/include/ndbapi/NdbIndexScanOperation.hpp:
new method for saving BOUNDS
ndb/include/ndbapi/NdbOperation.hpp:
Remove bounds stuff from NdbOperation and put it into NdbScanOperation
ndb/include/ndbapi/NdbScanOperation.hpp:
reset bounds
ndb/src/common/debugger/signaldata/Makefile.am:
New signal data printer for ScanFrag
ndb/src/common/debugger/signaldata/ScanTab.cpp:
Fix printout
ndb/src/common/debugger/signaldata/SignalDataPrint.cpp:
New signal data printer for ScanFrag
ndb/src/kernel/blocks/backup/Backup.cpp:
Updated ScanFragReq
ndb/src/kernel/blocks/dblqh/Dblqh.hpp:
Use same sendKeyInfo for both acckeyreq and tux_bounds
ndb/src/kernel/blocks/dblqh/DblqhMain.cpp:
Let range scan use KEYinfo for bounds instead of attrinfo
ndb/src/kernel/blocks/dbtc/Dbtc.hpp:
Let range scan use KEYinfo for bounds instead of attrinfo
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp:
Handle keyinfo in range scan
ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp:
Skip useless 5 words in beginning of TuxBounds
ndb/src/kernel/blocks/suma/Suma.cpp:
Fix SCAN_FRAGREQ
ndb/src/ndbapi/NdbConnection.cpp:
reset bounds
ndb/src/ndbapi/NdbOperation.cpp:
Remove bounds
ndb/src/ndbapi/NdbOperationDefine.cpp:
Remove bounds stuff
ndb/src/ndbapi/NdbOperationInt.cpp:
Remove bounds stuff
ndb/src/ndbapi/NdbScanOperation.cpp:
Send BOUNDS in KEYINFO instead of ATTRINFO
Diffstat (limited to 'ndb/src')
-rw-r--r-- | ndb/src/common/debugger/signaldata/Makefile.am | 3 | ||||
-rw-r--r-- | ndb/src/common/debugger/signaldata/ScanTab.cpp | 6 | ||||
-rw-r--r-- | ndb/src/common/debugger/signaldata/SignalDataPrint.cpp | 2 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/backup/Backup.cpp | 2 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dblqh/Dblqh.hpp | 2 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 66 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbtc/Dbtc.hpp | 7 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbtc/DbtcMain.cpp | 112 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp | 4 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/suma/Suma.cpp | 2 | ||||
-rw-r--r-- | ndb/src/ndbapi/NdbConnection.cpp | 21 | ||||
-rw-r--r-- | ndb/src/ndbapi/NdbOperation.cpp | 10 | ||||
-rw-r--r-- | ndb/src/ndbapi/NdbOperationDefine.cpp | 4 | ||||
-rw-r--r-- | ndb/src/ndbapi/NdbOperationInt.cpp | 4 | ||||
-rw-r--r-- | ndb/src/ndbapi/NdbScanOperation.cpp | 307 |
15 files changed, 334 insertions, 218 deletions
diff --git a/ndb/src/common/debugger/signaldata/Makefile.am b/ndb/src/common/debugger/signaldata/Makefile.am index 0a5806e1e00..c855c5f8a18 100644 --- a/ndb/src/common/debugger/signaldata/Makefile.am +++ b/ndb/src/common/debugger/signaldata/Makefile.am @@ -23,7 +23,8 @@ libsignaldataprint_la_SOURCES = \ FailRep.cpp DisconnectRep.cpp SignalDroppedRep.cpp \ SumaImpl.cpp NdbSttor.cpp CreateFragmentation.cpp \ UtilLock.cpp TuxMaint.cpp AccLock.cpp \ - LqhTrans.cpp ReadNodesConf.cpp CntrStart.cpp + LqhTrans.cpp ReadNodesConf.cpp CntrStart.cpp \ + ScanFrag.cpp include $(top_srcdir)/ndb/config/common.mk.am include $(top_srcdir)/ndb/config/type_ndbapi.mk.am diff --git a/ndb/src/common/debugger/signaldata/ScanTab.cpp b/ndb/src/common/debugger/signaldata/ScanTab.cpp index 3f2109d9477..05da1251275 100644 --- a/ndb/src/common/debugger/signaldata/ScanTab.cpp +++ b/ndb/src/common/debugger/signaldata/ScanTab.cpp @@ -37,8 +37,10 @@ printSCANTABREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiv sig->getHoldLockFlag(requestInfo), sig->getRangeScanFlag(requestInfo)); - fprintf(output, " attrLen: %d, tableId: %d, tableSchemaVer: %d\n", - sig->attrLen, sig->tableId, sig->tableSchemaVersion); + Uint32 keyLen = (sig->attrLenKeyLen >> 16); + Uint32 attrLen = (sig->attrLenKeyLen & 0xFFFF); + fprintf(output, " attrLen: %d, keyLen: %d tableId: %d, tableSchemaVer: %d\n", + attrLen, keyLen, sig->tableId, sig->tableSchemaVersion); fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x) storedProcId: H\'%.8x\n", sig->transId1, sig->transId2, sig->storedProcId); diff --git a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp index 65351663789..640449a0579 100644 --- a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp +++ b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp @@ -53,6 +53,7 @@ #include <signaldata/UtilPrepare.hpp> #include <signaldata/UtilExecute.hpp> #include <signaldata/ScanTab.hpp> +#include <signaldata/ScanFrag.hpp> #include <signaldata/LqhFrag.hpp> #include <signaldata/LqhTransConf.hpp> #include <signaldata/DropTab.hpp> @@ -250,6 +251,7 @@ SignalDataPrintFunctions[] = { ,{ GSN_TUX_MAINT_REQ, printTUX_MAINT_REQ } ,{ GSN_ACC_LOCKREQ, printACC_LOCKREQ } ,{ GSN_LQH_TRANSCONF, printLQH_TRANSCONF } + ,{ GSN_SCAN_FRAGREQ, printSCAN_FRAGREQ } }; const unsigned short NO_OF_PRINT_FUNCTIONS = sizeof(SignalDataPrintFunctions)/sizeof(NameFunctionPair); diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp index 08a8bf83e20..569b3f98faa 100644 --- a/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/ndb/src/kernel/blocks/backup/Backup.cpp @@ -3360,7 +3360,7 @@ Backup::execBACKUP_FRAGMENT_REQ(Signal* signal) req->senderData = filePtr.i; req->resultRef = reference(); req->schemaVersion = table.schemaVersion; - req->fragmentNo = fragNo; + req->fragmentNoKeyLen = fragNo; req->requestInfo = 0; req->savePointId = 0; req->tableId = table.tableId; diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index a94af7b59c8..b4531af7cd6 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -2248,7 +2248,7 @@ private: void sendAttrinfoLoop(Signal* signal); void sendAttrinfoSignal(Signal* signal); void sendLqhAttrinfoSignal(Signal* signal); - void sendKeyinfoAcc(Signal* signal); + void sendKeyinfoAcc(Signal* signal, Uint32 pos); Uint32 initScanrec(const class ScanFragReq *); void initScanTc(Signal* signal, Uint32 transid1, diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 8342870d69c..c5e2bd900e9 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -2803,8 +2803,10 @@ void Dblqh::execKEYINFO(Signal* signal) return; }//if TcConnectionrec * const regTcPtr = tcConnectptr.p; - if (regTcPtr->transactionState != - TcConnectionrec::WAIT_TUPKEYINFO) { + TcConnectionrec::TransactionState state = regTcPtr->transactionState; + if (state != TcConnectionrec::WAIT_TUPKEYINFO && + state != TcConnectionrec::WAIT_SCAN_AI) + { jam(); /*****************************************************************************/ /* TRANSACTION WAS ABORTED, THIS IS MOST LIKELY A SIGNAL BELONGING TO THE */ @@ -2822,15 +2824,19 @@ void Dblqh::execKEYINFO(Signal* signal) return; }//if jam(); + abort(); terrorCode = errorCode; abortErrorLab(signal); return; }//if - FragrecordPtr regFragptr; - regFragptr.i = regTcPtr->fragmentptr; - ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord); - fragptr = regFragptr; - endgettupkeyLab(signal); + if(state == TcConnectionrec::WAIT_TUPKEYINFO) + { + FragrecordPtr regFragptr; + regFragptr.i = regTcPtr->fragmentptr; + ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord); + fragptr = regFragptr; + endgettupkeyLab(signal); + } return; }//Dblqh::execKEYINFO() @@ -2838,9 +2844,9 @@ void Dblqh::execKEYINFO(Signal* signal) /* FILL IN KEY DATA INTO DATA BUFFERS. */ /* ------------------------------------------------------------------------- */ Uint32 Dblqh::handleLongTupKey(Signal* signal, - Uint32 keyLength, - Uint32 primKeyLength, - Uint32* dataPtr) + Uint32 keyLength, + Uint32 primKeyLength, + Uint32* dataPtr) { TcConnectionrec * const regTcPtr = tcConnectptr.p; Uint32 dataPos = 0; @@ -3686,7 +3692,7 @@ void Dblqh::prepareContinueAfterBlockedLab(Signal* signal) signal->theData[9] = sig3; signal->theData[10] = sig4; if (regTcPtr->primKeyLen > 4) { - sendKeyinfoAcc(signal); + sendKeyinfoAcc(signal, 11); }//if EXECUTE_DIRECT(refToBlock(regTcPtr->tcAccBlockref), GSN_ACCKEYREQ, signal, 7 + regTcPtr->primKeyLen); @@ -3708,9 +3714,8 @@ void Dblqh::prepareContinueAfterBlockedLab(Signal* signal) /* ======= SEND KEYINFO TO ACC ======= */ /* */ /* ========================================================================== */ -void Dblqh::sendKeyinfoAcc(Signal* signal) +void Dblqh::sendKeyinfoAcc(Signal* signal, Uint32 Ti) { - UintR Ti = 11; DatabufPtr regDatabufptr; regDatabufptr.i = tcConnectptr.p->firstTupkeybuf; @@ -7409,7 +7414,8 @@ void Dblqh::execSCAN_FRAGREQ(Signal* signal) jamEntry(); const Uint32 reqinfo = scanFragReq->requestInfo; - const Uint32 fragId = scanFragReq->fragmentNo; + const Uint32 fragId = (scanFragReq->fragmentNoKeyLen & 0xFFFF); + const Uint32 keyLen = (scanFragReq->fragmentNoKeyLen >> 16); tabptr.i = scanFragReq->tableId; const Uint32 max_rows = scanFragReq->batch_size_rows; const Uint32 scanLockMode = ScanFragReq::getLockMode(reqinfo); @@ -7473,6 +7479,8 @@ void Dblqh::execSCAN_FRAGREQ(Signal* signal) transid2, fragId, ZNIL); + tcConnectptr.p->save1 = 4; + tcConnectptr.p->primKeyLen = keyLen + 4; // hard coded in execKEYINFO errorCode = initScanrec(scanFragReq); if (errorCode != ZOK) { jam(); @@ -7672,34 +7680,18 @@ void Dblqh::accScanConfScanLab(Signal* signal) return; }//if scanptr.p->scanAccPtr = accScanConf->accPtr; - AttrbufPtr regAttrinbufptr; - regAttrinbufptr.i = tcConnectptr.p->firstAttrinbuf; - Uint32 boundAiLength = 0; + Uint32 boundAiLength = tcConnectptr.p->primKeyLen - 4; if (scanptr.p->rangeScan) { jam(); // bound info length is in first of the 5 header words - ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf); - boundAiLength = regAttrinbufptr.p->attrbuf[0]; TuxBoundInfo* const req = (TuxBoundInfo*)signal->getDataPtrSend(); req->errorCode = RNIL; req->tuxScanPtrI = scanptr.p->scanAccPtr; req->boundAiLength = boundAiLength; - Uint32* out = (Uint32*)req + TuxBoundInfo::SignalLength; - Uint32 sz = 0; - while (sz < boundAiLength) { - jam(); - ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf); - Uint32 dataLen = regAttrinbufptr.p->attrbuf[ZINBUF_DATA_LEN]; - MEMCOPY_NO_WORDS(&out[sz], - ®Attrinbufptr.p->attrbuf[0], - dataLen); - sz += dataLen; - regAttrinbufptr.i = regAttrinbufptr.p->attrbuf[ZINBUF_NEXT]; - ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf); - } - ndbrequire(sz == boundAiLength); + if(boundAiLength > 0) + sendKeyinfoAcc(signal, TuxBoundInfo::SignalLength); EXECUTE_DIRECT(DBTUX, GSN_TUX_BOUND_INFO, - signal, TuxBoundInfo::SignalLength + boundAiLength); + signal, TuxBoundInfo::SignalLength + boundAiLength); jamEntry(); if (req->errorCode != 0) { jam(); @@ -7716,12 +7708,14 @@ void Dblqh::accScanConfScanLab(Signal* signal) signal->theData[1] = tcConnectptr.p->tableref; signal->theData[2] = scanptr.p->scanSchemaVersion; signal->theData[3] = ZSTORED_PROC_SCAN; - ndbrequire(boundAiLength <= scanptr.p->scanAiLength); - signal->theData[4] = scanptr.p->scanAiLength - boundAiLength; + + signal->theData[4] = scanptr.p->scanAiLength; sendSignal(tcConnectptr.p->tcTupBlockref, GSN_STORED_PROCREQ, signal, 5, JBB); signal->theData[0] = tcConnectptr.p->tupConnectrec; + AttrbufPtr regAttrinbufptr; + regAttrinbufptr.i = tcConnectptr.p->firstAttrinbuf; while (regAttrinbufptr.i != RNIL) { ptrCheckGuard(regAttrinbufptr, cattrinbufFileSize, attrbuf); jam(); diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index a5f07f8e9e1..2ac3149195d 100644 --- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -192,7 +192,8 @@ public: OS_WAIT_ATTR = 14, OS_WAIT_COMMIT_CONF = 15, OS_WAIT_ABORT_CONF = 16, - OS_WAIT_COMPLETE_CONF = 17 + OS_WAIT_COMPLETE_CONF = 17, + OS_WAIT_SCAN = 18 }; enum AbortState { @@ -1169,6 +1170,8 @@ public: // Length of expected attribute information Uint32 scanAiLength; + Uint32 scanKeyLen; + // Reference to ApiConnectRecord Uint32 scanApiRec; @@ -1571,7 +1574,7 @@ private: void diFcountReqLab(Signal* signal, ScanRecordPtr); void signalErrorRefuseLab(Signal* signal); void abort080Lab(Signal* signal); - void packKeyData000Lab(Signal* signal, BlockReference TBRef); + void packKeyData000Lab(Signal* signal, BlockReference TBRef, Uint32 len); void abortScanLab(Signal* signal, ScanRecordPtr, Uint32 errCode); void sendAbortedAfterTimeout(Signal* signal, int Tcheck); void abort010Lab(Signal* signal); diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 5b5578cb579..75d14f717e7 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -1751,6 +1751,7 @@ void Dbtc::execKEYINFO(Signal* signal) switch (apiConnectptr.p->apiConnectstate) { case CS_RECEIVING: case CS_REC_COMMITTING: + case CS_START_SCAN: jam(); /*empty*/; break; @@ -1804,12 +1805,54 @@ void Dbtc::execKEYINFO(Signal* signal) jam(); tckeyreq020Lab(signal); return; + case OS_WAIT_SCAN: + break; default: jam(); terrorCode = ZSTATE_ERROR; abortErrorLab(signal); return; }//switch + + UintR TdataPos = 0; + UintR TkeyLen = regCachePtr->keylen; + UintR Tlen = regCachePtr->save1; + + do { + if (cfirstfreeDatabuf == RNIL) { + jam(); + abort(); + seizeDatabuferrorLab(signal); + return; + }//if + linkKeybuf(signal); + arrGuard(TdataPos, 19); + databufptr.p->data[0] = signal->theData[TdataPos + 3]; + databufptr.p->data[1] = signal->theData[TdataPos + 4]; + databufptr.p->data[2] = signal->theData[TdataPos + 5]; + databufptr.p->data[3] = signal->theData[TdataPos + 6]; + Tlen = Tlen + 4; + TdataPos = TdataPos + 4; + if (Tlen < TkeyLen) { + jam(); + if (TdataPos >= tmaxData) { + jam(); + /*----------------------------------------------------*/ + /** EXIT AND WAIT FOR SIGNAL KEYINFO OR KEYINFO9 **/ + /** WHEN EITHER OF THE SIGNALS IS RECEIVED A JUMP **/ + /** TO LABEL "KEYINFO_LABEL" IS DONE. THEN THE **/ + /** PROGRAM RETURNS TO LABEL TCKEYREQ020 **/ + /*----------------------------------------------------*/ + setApiConTimer(apiConnectptr.i, ctcTimer, __LINE__); + regCachePtr->save1 = Tlen; + return; + }//if + } else { + jam(); + return; + }//if + } while (1); + return; }//Dbtc::execKEYINFO() /*---------------------------------------------------------------------------*/ @@ -1818,45 +1861,45 @@ void Dbtc::execKEYINFO(Signal* signal) /* WE WILL ALWAYS PACK 4 WORDS AT A TIME. */ /*---------------------------------------------------------------------------*/ void Dbtc::packKeyData000Lab(Signal* signal, - BlockReference TBRef) + BlockReference TBRef, + Uint32 totalLen) { CacheRecord * const regCachePtr = cachePtr.p; UintR Tmp; - Uint16 tdataPos; jam(); - tdataPos = 0; - Tmp = regCachePtr->keylen; + Uint32 len = 0; databufptr.i = regCachePtr->firstKeybuf; + signal->theData[0] = tcConnectptr.i; + signal->theData[1] = apiConnectptr.p->transid[0]; + signal->theData[2] = apiConnectptr.p->transid[1]; + Uint32 * dst = signal->theData+3; + ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord); + do { jam(); - if (tdataPos == 20) { - jam(); - /*---------------------------------------------------------------------*/ - /* 4 MORE WORDS WILL NOT FIT IN THE 24 DATA WORDS IN A SIGNAL */ - /*---------------------------------------------------------------------*/ - sendKeyinfo(signal, TBRef, 20); - tdataPos = 0; - }//if - Tmp = Tmp - 4; - ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord); - cdata[tdataPos ] = databufptr.p->data[0]; - cdata[tdataPos + 1] = databufptr.p->data[1]; - cdata[tdataPos + 2] = databufptr.p->data[2]; - cdata[tdataPos + 3] = databufptr.p->data[3]; - tdataPos = tdataPos + 4; - if (Tmp <= 4) { + databufptr.i = databufptr.p->nextDatabuf; + dst[len + 0] = databufptr.p->data[0]; + dst[len + 1] = databufptr.p->data[1]; + dst[len + 2] = databufptr.p->data[2]; + dst[len + 3] = databufptr.p->data[3]; + len += 4; + if (totalLen <= 4) { jam(); /*---------------------------------------------------------------------*/ /* LAST PACK OF KEY DATA HAVE BEEN SENT */ /*---------------------------------------------------------------------*/ /* THERE WERE UNSENT INFORMATION, SEND IT. */ /*---------------------------------------------------------------------*/ - sendKeyinfo(signal, TBRef, tdataPos); - releaseKeys(); + sendSignal(TBRef, GSN_KEYINFO, signal, 3 + len, JBB); return; - }//if - databufptr.i = databufptr.p->nextDatabuf; + } else if(len == KeyInfo::DataLength){ + jam(); + len = 0; + sendSignal(TBRef, GSN_KEYINFO, signal, 3 + KeyInfo::DataLength, JBB); + } + totalLen -= 4; + ptrCheckGuard(databufptr, cdatabufFilesize, databufRecord); } while (1); }//Dbtc::packKeyData000Lab() @@ -3006,7 +3049,8 @@ void Dbtc::packLqhkeyreq(Signal* signal, UintR TfirstAttrbuf = regCachePtr->firstAttrbuf; sendlqhkeyreq(signal, TBRef); if (Tkeylen > 4) { - packKeyData000Lab(signal, TBRef); + packKeyData000Lab(signal, TBRef, Tkeylen - 4); + releaseKeys(); }//if packLqhkeyreq040Lab(signal, TfirstAttrbuf, @@ -8398,7 +8442,8 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) { const ScanTabReq * const scanTabReq = (ScanTabReq *)&signal->theData[0]; const Uint32 reqinfo = scanTabReq->requestInfo; - const Uint32 aiLength = scanTabReq->attrLen; + const Uint32 aiLength = (scanTabReq->attrLenKeyLen & 0xFFFF); + const Uint32 keyLen = scanTabReq->attrLenKeyLen >> 16; const Uint32 schemaVersion = scanTabReq->tableSchemaVersion; const Uint32 transid1 = scanTabReq->transId1; const Uint32 transid2 = scanTabReq->transId2; @@ -8472,8 +8517,12 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) seizeTcConnect(signal); tcConnectptr.p->apiConnect = apiConnectptr.i; + tcConnectptr.p->tcConnectstate = OS_WAIT_SCAN; + apiConnectptr.p->lastTcConnect = tcConnectptr.i; seizeCacheRecord(signal); + cachePtr.p->keylen = keyLen; + cachePtr.p->save1 = 0; scanptr = seizeScanrec(signal); ndbrequire(transP->apiScanRec == RNIL); @@ -8554,7 +8603,8 @@ void Dbtc::initScanrec(ScanRecordPtr scanptr, scanptr.p->scanTcrec = tcConnectptr.i; scanptr.p->scanApiRec = apiConnectptr.i; - scanptr.p->scanAiLength = scanTabReq->attrLen; + scanptr.p->scanAiLength = scanTabReq->attrLenKeyLen & 0xFFFF; + scanptr.p->scanKeyLen = scanTabReq->attrLenKeyLen >> 16; scanptr.p->scanTableref = tabptr.i; scanptr.p->scanSchemaVersion = scanTabReq->tableSchemaVersion; scanptr.p->scanParallel = scanParallel; @@ -8799,6 +8849,7 @@ void Dbtc::releaseScanResources(ScanRecordPtr scanPtr) if (apiConnectptr.p->cachePtr != RNIL) { cachePtr.i = apiConnectptr.p->cachePtr; ptrCheckGuard(cachePtr, ccacheFilesize, cacheRecord); + releaseKeys(); releaseAttrinfo(); }//if tcConnectptr.i = scanPtr.p->scanTcrec; @@ -9458,7 +9509,7 @@ void Dbtc::sendScanFragReq(Signal* signal, ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); req->senderData = scanFragptr.i; req->requestInfo = requestInfo; - req->fragmentNo = scanFragP->scanFragId; + req->fragmentNoKeyLen = scanFragP->scanFragId | (scanP->scanKeyLen << 16); req->resultRef = apiConnectptr.p->ndbapiBlockref; req->savePointId = apiConnectptr.p->currSavePointId; req->transId1 = apiConnectptr.p->transid[0]; @@ -9468,6 +9519,11 @@ void Dbtc::sendScanFragReq(Signal* signal, req->batch_size_bytes= scanP->batch_byte_size; sendSignal(scanFragP->lqhBlockref, GSN_SCAN_FRAGREQ, signal, ScanFragReq::SignalLength, JBB); + if(scanP->scanKeyLen > 0) + { + tcConnectptr.i = scanFragptr.i; + packKeyData000Lab(signal, scanFragP->lqhBlockref, scanP->scanKeyLen); + } updateBuddyTimer(apiConnectptr); scanFragP->startFragTimer(ctcTimer); }//Dbtc::sendScanFragReq() diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp index 5b161d3c4ce..7414691ab78 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp @@ -129,14 +129,14 @@ Dbtux::execTUX_BOUND_INFO(Signal* signal) // largest attrId seen plus one Uint32 maxAttrId = 0; // skip 5 words - if (req->boundAiLength < 5) { + unsigned offset = 0; + if (req->boundAiLength < offset) { jam(); scan.m_state = ScanOp::Invalid; sig->errorCode = TuxBoundInfo::InvalidAttrInfo; return; } const Uint32* const data = (Uint32*)sig + TuxBoundInfo::SignalLength; - unsigned offset = 5; // walk through entries while (offset + 2 <= req->boundAiLength) { jam(); diff --git a/ndb/src/kernel/blocks/suma/Suma.cpp b/ndb/src/kernel/blocks/suma/Suma.cpp index 052809cb084..8e651343ab7 100644 --- a/ndb/src/kernel/blocks/suma/Suma.cpp +++ b/ndb/src/kernel/blocks/suma/Suma.cpp @@ -1891,7 +1891,7 @@ SumaParticipant::SyncRecord::nextScan(Signal* signal){ ScanFragReq::setHoldLockFlag(req->requestInfo, 0); ScanFragReq::setKeyinfoFlag(req->requestInfo, 0); ScanFragReq::setAttrLen(req->requestInfo, attrLen); - req->fragmentNo = fd.m_fragDesc.m_fragmentNo; + req->fragmentNoKeyLen = fd.m_fragDesc.m_fragmentNo; req->schemaVersion = tabPtr.p->m_schemaVersion; req->transId1 = 0; req->transId2 = (SUMA << 20) + (suma.getOwnNodeId() << 8); diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp index 8ab0d13c67f..b89cc7112f4 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbConnection.cpp @@ -1115,15 +1115,8 @@ NdbConnection::getNdbScanOperation(const NdbTableImpl * tab) if (tOp == NULL) goto getNdbOp_error1; - // Link scan operation into list of cursor operations - if (m_theLastScanOperation == NULL) - m_theFirstScanOperation = m_theLastScanOperation = tOp; - else { - m_theLastScanOperation->next(tOp); - m_theLastScanOperation = tOp; - } - tOp->next(NULL); if (tOp->init(tab, this) != -1) { + define_scan_op(tOp); return tOp; } else { theNdb->releaseScanOperation(tOp); @@ -1135,6 +1128,18 @@ getNdbOp_error1: return NULL; }//NdbConnection::getNdbScanOperation() +void +NdbConnection::define_scan_op(NdbIndexScanOperation * tOp){ + // Link scan operation into list of cursor operations + if (m_theLastScanOperation == NULL) + m_theFirstScanOperation = m_theLastScanOperation = tOp; + else { + m_theLastScanOperation->next(tOp); + m_theLastScanOperation = tOp; + } + tOp->next(NULL); +} + NdbScanOperation* NdbConnection::getNdbScanOperation(const NdbDictionary::Table * table) { diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp index 53a94d98a5a..b0b95d0ff43 100644 --- a/ndb/src/ndbapi/NdbOperation.cpp +++ b/ndb/src/ndbapi/NdbOperation.cpp @@ -78,7 +78,6 @@ NdbOperation::NdbOperation(Ndb* aNdb) : m_tcReqGSN(GSN_TCKEYREQ), m_keyInfoGSN(GSN_KEYINFO), m_attrInfoGSN(GSN_ATTRINFO), - theBoundATTRINFO(NULL), theBlobList(NULL) { theReceiver.init(NdbReceiver::NDB_OPERATION, this); @@ -167,7 +166,6 @@ NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){ theScanInfo = 0; theTotalNrOfKeyWordInSignal = 8; theMagicNumber = 0xABCDEF01; - theBoundATTRINFO = NULL; theBlobList = NULL; tSignal = theNdb->getSignal(); @@ -263,14 +261,6 @@ NdbOperation::release() tSubroutine = tSubroutine->theNext; theNdb->releaseNdbSubroutine(tSaveSubroutine); } - tSignal = theBoundATTRINFO; - while (tSignal != NULL) - { - tSaveSignal = tSignal; - tSignal = tSignal->next(); - theNdb->releaseSignal(tSaveSignal); - } - theBoundATTRINFO = NULL; } tBlob = theBlobList; while (tBlob != NULL) diff --git a/ndb/src/ndbapi/NdbOperationDefine.cpp b/ndb/src/ndbapi/NdbOperationDefine.cpp index ad838ddd601..20660a4d990 100644 --- a/ndb/src/ndbapi/NdbOperationDefine.cpp +++ b/ndb/src/ndbapi/NdbOperationDefine.cpp @@ -316,10 +316,6 @@ NdbOperation::getValue_impl(const NdbColumnImpl* tAttrInfo, char* aValue) if ((tAttrInfo != NULL) && (!tAttrInfo->m_indexOnly) && (theStatus != Init)){ - if (theStatus == SetBound) { - ((NdbIndexScanOperation*)this)->saveBoundATTRINFO(); - theStatus = GetValue; - } if (theStatus != GetValue) { if (theInterpretIndicator == 1) { if (theStatus == FinalGetValue) { diff --git a/ndb/src/ndbapi/NdbOperationInt.cpp b/ndb/src/ndbapi/NdbOperationInt.cpp index f5d334fd79a..ee7b8132cd1 100644 --- a/ndb/src/ndbapi/NdbOperationInt.cpp +++ b/ndb/src/ndbapi/NdbOperationInt.cpp @@ -216,10 +216,6 @@ int NdbOperation::initial_interpreterCheck() { if ((theInterpretIndicator == 1)) { - if (theStatus == SetBound) { - ((NdbIndexScanOperation*)this)->saveBoundATTRINFO(); - theStatus = GetValue; - } if (theStatus == ExecInterpretedValue) { return 0; // Simply continue with interpretation } else if (theStatus == GetValue) { diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 3ff2a32d418..33118df0160 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -32,6 +32,7 @@ #include <signaldata/ScanTab.hpp> #include <signaldata/KeyInfo.hpp> +#include <signaldata/AttrInfo.hpp> #include <signaldata/TcKeyReq.hpp> NdbScanOperation::NdbScanOperation(Ndb* aNdb) : @@ -116,10 +117,6 @@ NdbScanOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection) theStatus = GetValue; theOperationType = OpenScanRequest; - - theTotalBoundAI_Len = 0; - theBoundATTRINFO = NULL; - return 0; } @@ -181,7 +178,7 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, } assert (m_currentTable != m_accessTable); // Modify operation state - theStatus = SetBound; + theStatus = GetValue; theOperationType = OpenRangeScanRequest; range = true; } @@ -219,8 +216,14 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, req->transId1 = (Uint32) transId; req->transId2 = (Uint32) (transId >> 32); - getFirstATTRINFOScan(); + NdbApiSignal* tSignal = + theFirstKEYINFO = theLastKEYINFO = theNdb->getSignal(); + + tSignal->setSignal(GSN_KEYINFO); + theKEYINFOptr = ((KeyInfo*)tSignal->getDataPtrSend())->keyData; + theTotalNrOfKeyWordInSignal= 0; + getFirstATTRINFOScan(); return getResultSet(); } @@ -355,6 +358,7 @@ NdbScanOperation::getFirstATTRINFOScan() * After setBound() are done, move the accumulated ATTRINFO signals to * a separate list. Then continue with normal scan. */ +#if 0 int NdbIndexScanOperation::saveBoundATTRINFO() { @@ -401,6 +405,7 @@ NdbIndexScanOperation::saveBoundATTRINFO() } return res; } +#endif #define WAITFOR_SCAN_TIMEOUT 120000 @@ -428,7 +433,6 @@ NdbScanOperation::executeCursor(int nodeId){ TRACE_DEBUG("The node is hard dead when attempting to start a scan"); setErrorCode(4029); tCon->theReleaseOnClose = true; - abort(); } else { TRACE_DEBUG("The node is stopping when attempting to start a scan"); setErrorCode(4030); @@ -635,7 +639,7 @@ NdbScanOperation::doSend(int ProcessorId) void NdbScanOperation::closeScan() { - if(m_transConnection) do { + if(m_transConnection){ if(DEBUG_NEXT_RESULT) ndbout_c("closeScan() theError.code = %d " "m_api_receivers_count = %d " @@ -648,55 +652,8 @@ void NdbScanOperation::closeScan() TransporterFacade* tp = TransporterFacade::instance(); Guard guard(tp->theMutexPtr); - - Uint32 seq = theNdbCon->theNodeSequence; - Uint32 nodeId = theNdbCon->theDBnode; - - if(seq != tp->getNodeSequence(nodeId)){ - theNdbCon->theReleaseOnClose = true; - break; - } - - while(theError.code == 0 && m_sent_receivers_count){ - theNdb->theWaiter.m_node = nodeId; - theNdb->theWaiter.m_state = WAIT_SCAN; - int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); - switch(return_code){ - case 0: - break; - case -1: - setErrorCode(4008); - case -2: - m_api_receivers_count = 0; - m_conf_receivers_count = 0; - m_sent_receivers_count = 0; - theNdbCon->theReleaseOnClose = true; - } - } - - if(m_api_receivers_count+m_conf_receivers_count){ - // Send close scan - send_next_scan(0, true); // Close scan - } + close_impl(tp); - /** - * wait for close scan conf - */ - while(m_sent_receivers_count+m_api_receivers_count+m_conf_receivers_count){ - theNdb->theWaiter.m_node = nodeId; - theNdb->theWaiter.m_state = WAIT_SCAN; - int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); - switch(return_code){ - case 0: - break; - case -1: - setErrorCode(4008); - case -2: - m_api_receivers_count = 0; - m_conf_receivers_count = 0; - m_sent_receivers_count = 0; - } - } } while(0); theNdbCon->theScanningOp = 0; @@ -750,11 +707,6 @@ int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr, return -1; } - if (theStatus == SetBound) { - ((NdbIndexScanOperation*)this)->saveBoundATTRINFO(); - theStatus = GetValue; - } - theErrorLine = 0; // In preapareSendInterpreted we set the sizes (word 4-8) in the @@ -769,23 +721,7 @@ int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr, const Uint32 transId1 = (Uint32) (aTransactionId & 0xFFFFFFFF); const Uint32 transId2 = (Uint32) (aTransactionId >> 32); - if (theOperationType == OpenRangeScanRequest) { - NdbApiSignal* tSignal = theBoundATTRINFO; - do{ - tSignal->setData(aTC_ConnectPtr, 1); - tSignal->setData(transId1, 2); - tSignal->setData(transId2, 3); - tSignal = tSignal->next(); - } while (tSignal != NULL); - } theCurrentATTRINFO->setLength(theAI_LenInCurrAI); - NdbApiSignal* tSignal = theFirstATTRINFO; - do{ - tSignal->setData(aTC_ConnectPtr, 1); - tSignal->setData(transId1, 2); - tSignal->setData(transId2, 3); - tSignal = tSignal->next(); - } while (tSignal != NULL); /** * Prepare all receivers @@ -841,13 +777,18 @@ NdbScanOperation::doSendScan(int aProcessorId) setErrorCode(4001); return -1; } + + Uint32 tupKeyLen = theTupKeyLen; + Uint32 len = theTotalNrOfKeyWordInSignal; + Uint32 aTC_ConnectPtr = theNdbCon->theTCConPtr; + Uint64 transId = theNdbCon->theTransactionId; + // Update the "attribute info length in words" in SCAN_TABREQ before // sending it. This could not be done in openScan because // we created the ATTRINFO signals after the SCAN_TABREQ signal. ScanTabReq * const req = CAST_PTR(ScanTabReq, tSignal->getDataPtrSend()); - req->attrLen = theTotalCurrAI_Len; - if (theOperationType == OpenRangeScanRequest) - req->attrLen += theTotalBoundAI_Len; + req->attrLenKeyLen = (tupKeyLen << 16) | theTotalCurrAI_Len; + TransporterFacade *tp = TransporterFacade::instance(); LinearSectionPtr ptr[3]; ptr[0].p = m_prepared_receivers; @@ -856,22 +797,41 @@ NdbScanOperation::doSendScan(int aProcessorId) setErrorCode(4002); return -1; } - if (theOperationType == OpenRangeScanRequest) { + + if (tupKeyLen > 0){ // must have at least one signal since it contains attrLen for bounds - assert(theBoundATTRINFO != NULL); - tSignal = theBoundATTRINFO; - while (tSignal != NULL) { + assert(theLastKEYINFO != NULL); + tSignal = theLastKEYINFO; + tSignal->setLength(KeyInfo::HeaderLength + theTotalNrOfKeyWordInSignal); + + assert(theFirstKEYINFO != NULL); + tSignal = theFirstKEYINFO; + + NdbApiSignal* last; + do { + KeyInfo * keyInfo = CAST_PTR(KeyInfo, tSignal->getDataPtrSend()); + keyInfo->connectPtr = aTC_ConnectPtr; + keyInfo->transId[0] = Uint32(transId); + keyInfo->transId[1] = Uint32(transId >> 32); + if (tp->sendSignal(tSignal,aProcessorId) == -1){ - setErrorCode(4002); - return -1; + setErrorCode(4002); + return -1; } + tSignalCount++; + last = tSignal; tSignal = tSignal->next(); - } + } while(last != theLastKEYINFO); } tSignal = theFirstATTRINFO; while (tSignal != NULL) { + AttrInfo * attrInfo = CAST_PTR(AttrInfo, tSignal->getDataPtrSend()); + attrInfo->connectPtr = aTC_ConnectPtr; + attrInfo->transId[0] = Uint32(transId); + attrInfo->transId[1] = Uint32(transId >> 32); + if (tp->sendSignal(tSignal,aProcessorId) == -1){ setErrorCode(4002); return -1; @@ -1056,11 +1016,6 @@ NdbIndexScanOperation::getValue_impl(const NdbColumnImpl* attrInfo, return NdbScanOperation::getValue_impl(attrInfo, aValue); } - if (theStatus == SetBound) { - saveBoundATTRINFO(); - theStatus = GetValue; - } - int id = attrInfo->m_attrId; // In "real" table assert(m_accessTable->m_index); int sz = (int)m_accessTable->m_index->m_key_ids.size(); @@ -1101,12 +1056,13 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, int type, const void* aValue, Uint32 len) { if (theOperationType == OpenRangeScanRequest && - theStatus == SetBound && (0 <= type && type <= 4) && len <= 8000) { // insert bound type - insertATTRINFO(type); + Uint32 currLen = theTotalNrOfKeyWordInSignal; + Uint32 remaining = KeyInfo::DataLength - currLen; Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; + // normalize char bound CHARSET_INFO* cs = tAttrInfo->m_cs; Uint32 xfrmData[2000]; @@ -1130,19 +1086,34 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, Uint32 tIndexAttrId = tAttrInfo->m_attrId; Uint32 sizeInWords = (len + 3) / 4; AttributeHeader ah(tIndexAttrId, sizeInWords); - insertATTRINFO(ah.m_value); - if (len != 0) { - // insert attribute data - if ((UintPtr(aValue) & 0x3) == 0 && (len & 0x3) == 0) - insertATTRINFOloop((const Uint32*)aValue, sizeInWords); - else { - Uint32 tempData[2000]; - memcpy(tempData, aValue, len); + const Uint32 ahValue = ah.m_value; + + const bool aligned = (UintPtr(aValue) & 3) == 0; + const bool nobytes = (len & 0x3) == 0; + const Uint32 totalLen = 2 + sizeInWords; + Uint32 tupKeyLen = theTupKeyLen; + if(remaining > totalLen && aligned && nobytes){ + Uint32 * dst = theKEYINFOptr + currLen; + * dst ++ = type; + * dst ++ = ahValue; + memcpy(dst, aValue, 4 * sizeInWords); + theTotalNrOfKeyWordInSignal = currLen + totalLen; + } else { + if(!aligned || !nobytes){ + Uint32 tempData[2002]; + tempData[0] = type; + tempData[1] = ahValue; + memcpy(tempData+2, aValue, len); while ((len & 0x3) != 0) - ((char*)tempData)[len++] = 0; - insertATTRINFOloop(tempData, sizeInWords); + ((char*)&tempData[2])[len++] = 0; + insertBOUNDS(tempData, 2+sizeInWords); + } else { + Uint32 buf[2] = { type, ahValue }; + insertBOUNDS(buf, 2); + insertBOUNDS((Uint32*)aValue, sizeInWords); } } + theTupKeyLen = tupKeyLen + totalLen; /** * Do sorted stuff @@ -1165,6 +1136,46 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, } } +int +NdbIndexScanOperation::insertBOUNDS(Uint32 * data, Uint32 sz){ + Uint32 len; + Uint32 remaining = KeyInfo::DataLength - theTotalNrOfKeyWordInSignal; + Uint32 * dst = theKEYINFOptr + theTotalNrOfKeyWordInSignal; + do { + len = (sz < remaining ? sz : remaining); + memcpy(dst, data, 4 * len); + + if(sz >= remaining){ + NdbApiSignal* tCurr = theLastKEYINFO; + tCurr->setLength(KeyInfo::MaxSignalLength); + NdbApiSignal* tSignal = tCurr->next(); + if(tSignal) + ; + else if((tSignal = theNdb->getSignal()) != 0) + { + tCurr->next(tSignal); + tSignal->setSignal(GSN_KEYINFO); + } else { + goto error; + } + theLastKEYINFO = tSignal; + theKEYINFOptr = dst = ((KeyInfo*)tSignal->getDataPtrSend())->keyData; + remaining = KeyInfo::DataLength; + sz -= len; + data += len; + } else { + len = (KeyInfo::DataLength - remaining) + len; + break; + } + } while(sz >= 0); + theTotalNrOfKeyWordInSignal = len; + return 0; + +error: + setErrorCodeAbort(4228); // XXX wrong code + return -1; +} + NdbResultSet* NdbIndexScanOperation::readTuples(LockMode lm, Uint32 batch, @@ -1173,9 +1184,23 @@ NdbIndexScanOperation::readTuples(LockMode lm, NdbResultSet * rs = NdbScanOperation::readTuples(lm, batch, 0); if(rs && order_by){ m_ordered = 1; - m_sort_columns = m_accessTable->getNoOfColumns() - 1; // -1 for NDB$NODE + Uint32 cnt = m_accessTable->getNoOfColumns() - 1; + m_sort_columns = cnt; // -1 for NDB$NODE m_current_api_receiver = m_sent_receivers_count; m_api_receivers_count = m_sent_receivers_count; + + m_sort_columns = cnt; + for(Uint32 i = 0; i<cnt; i++){ + const NdbColumnImpl* key = m_accessTable->m_index->m_columns[i]; + const NdbColumnImpl* col = m_currentTable->getColumn(key->m_keyInfoPos); + NdbRecAttr* tmp = NdbScanOperation::getValue_impl(col, (char*)-1); + UintPtr newVal = UintPtr(tmp); + theTupleKeyDefined[i][0] = FAKE_PTR; + theTupleKeyDefined[i][1] = (newVal & 0xFFFFFFFF); +#if (SIZEOF_CHARP == 8) + theTupleKeyDefined[i][2] = (newVal >> 32); +#endif + } } return rs; } @@ -1396,10 +1421,7 @@ NdbIndexScanOperation::send_next_scan_ordered(Uint32 idx){ } int -NdbScanOperation::restart(){ - TransporterFacade* tp = TransporterFacade::instance(); - Guard guard(tp->theMutexPtr); - +NdbScanOperation::close_impl(TransporterFacade* tp){ Uint32 seq = theNdbCon->theNodeSequence; Uint32 nodeId = theNdbCon->theDBnode; @@ -1407,8 +1429,8 @@ NdbScanOperation::restart(){ theNdbCon->theReleaseOnClose = true; return -1; } - - while(m_sent_receivers_count){ + + while(theError.code == 0 && m_sent_receivers_count){ theNdb->theWaiter.m_node = nodeId; theNdb->theWaiter.m_state = WAIT_SCAN; int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); @@ -1421,14 +1443,17 @@ NdbScanOperation::restart(){ m_api_receivers_count = 0; m_conf_receivers_count = 0; m_sent_receivers_count = 0; + theNdbCon->theReleaseOnClose = true; return -1; } } if(m_api_receivers_count+m_conf_receivers_count){ // Send close scan - if(send_next_scan(0, true) == -1) // Close scan + if(send_next_scan(0, true) == -1){ // Close scan + theNdbCon->theReleaseOnClose = true; return -1; + } } /** @@ -1447,15 +1472,15 @@ NdbScanOperation::restart(){ m_api_receivers_count = 0; m_conf_receivers_count = 0; m_sent_receivers_count = 0; + theNdbCon->theReleaseOnClose = true; return -1; } } + return 0; +} - /** - * Reset receivers - */ - const Uint32 parallell = theParallelism; - +void +NdbScanOperation::reset_receivers(Uint32 parallell, Uint32 ordered){ for(Uint32 i = 0; i<parallell; i++){ m_receivers[i]->m_list_index = i; m_prepared_receivers[i] = m_receivers[i]->getId(); @@ -1470,13 +1495,59 @@ NdbScanOperation::restart(){ m_sent_receivers_count = parallell; m_conf_receivers_count = 0; - if(m_ordered){ + if(ordered){ m_current_api_receiver = parallell; m_api_receivers_count = parallell; } +} + +int +NdbScanOperation::restart() +{ + + TransporterFacade* tp = TransporterFacade::instance(); + Guard guard(tp->theMutexPtr); + Uint32 nodeId = theNdbCon->theDBnode; + + { + int res; + if((res= close_impl(tp))) + { + return res; + } + } + + /** + * Reset receivers + */ + reset_receivers(theParallelism, m_ordered); if (doSendScan(nodeId) == -1) return -1; return 0; } + +int +NdbIndexScanOperation::reset_bounds(){ + int res; + + { + TransporterFacade* tp = TransporterFacade::instance(); + Guard guard(tp->theMutexPtr); + res= close_impl(tp); + } + + if(!res) + { + reset_receivers(theParallelism, m_ordered); + + theLastKEYINFO = theFirstKEYINFO; + theKEYINFOptr = ((KeyInfo*)theFirstKEYINFO->getDataPtrSend())->keyData; + theTotalNrOfKeyWordInSignal= 0; + + m_transConnection->define_scan_op(this); + return 0; + } + return res; +} |