18 #define DBTUX_SCAN_CPP
28 Dbtux::execACC_SCANREQ(
Signal* signal)
39 c_indexPool.
getPtr(indexPtr, req->tableId);
42 findFrag(*indexPtr.p, req->fragmentNo, fragPtr);
43 ndbrequire(fragPtr.i != RNIL);
44 Frag& frag = *fragPtr.p;
46 if (unlikely(indexPtr.p->m_state != Index::Online)) {
49 if (debugFlags & (DebugMeta | DebugScan)) {
50 debugOut <<
"Index dropping at ACC_SCANREQ " << indexPtr.i <<
" " << *indexPtr.p << endl;
53 errorCode = AccScanRef::TuxIndexNotOnline;
57 TreeHead& tree = frag.m_tree;
59 if (tree.m_root == NullTupLoc) {
62 conf->scanPtr = req->senderData;
64 conf->flag = AccScanConf::ZEMPTY_FRAGMENT;
65 sendSignal(req->senderRef, GSN_ACC_SCANCONF,
66 signal, AccScanConf::SignalLength, JBB);
70 if (ERROR_INSERTED(12008) ||
71 ! frag.m_scanList.seize(scanPtr)) {
72 CLEAR_ERROR_INSERT_VALUE;
75 errorCode = AccScanRef::TuxNoFreeScanOp;
78 new (scanPtr.p) ScanOp;
79 scanPtr.p->m_state = ScanOp::First;
80 scanPtr.p->m_userPtr = req->senderData;
81 scanPtr.p->m_userRef = req->senderRef;
82 scanPtr.p->m_tableId = indexPtr.p->m_tableId;
83 scanPtr.p->m_indexId = indexPtr.i;
84 scanPtr.p->m_fragId = fragPtr.p->m_fragId;
85 scanPtr.p->m_fragPtrI = fragPtr.i;
86 scanPtr.p->m_transId1 = req->transId1;
87 scanPtr.p->m_transId2 = req->transId2;
88 scanPtr.p->m_savePointId = req->savePointId;
89 scanPtr.p->m_readCommitted = AccScanReq::getReadCommittedFlag(req->requestInfo);
90 scanPtr.p->m_lockMode = AccScanReq::getLockMode(req->requestInfo);
91 scanPtr.p->m_descending = AccScanReq::getDescendingFlag(req->requestInfo);
98 const bool isStatScan = AccScanReq::getStatScanFlag(req->requestInfo);
99 if (unlikely(isStatScan)) {
101 if (!scanPtr.p->m_readCommitted) {
103 errorCode = AccScanRef::TuxInvalidLockMode;
107 if (!c_statOpPool.
seize(statPtr)) {
109 errorCode = AccScanRef::TuxNoFreeStatOp;
112 scanPtr.p->m_statOpPtrI = statPtr.i;
113 new (statPtr.p) StatOp(*indexPtr.p);
114 statPtr.p->m_scanOpPtrI = scanPtr.i;
117 if (debugFlags & DebugStat) {
118 debugOut <<
"Seize stat op" << endl;
123 if (debugFlags & DebugScan) {
124 debugOut <<
"Seize scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
129 conf->scanPtr = req->senderData;
130 conf->accPtr = scanPtr.i;
131 conf->flag = AccScanConf::ZNOT_EMPTY_FRAGMENT;
132 sendSignal(req->senderRef, GSN_ACC_SCANCONF,
133 signal, AccScanConf::SignalLength, JBB);
136 if (scanPtr.i != RNIL) {
138 releaseScanOp(scanPtr);
141 ndbrequire(errorCode != 0);
143 ref->scanPtr = req->senderData;
145 ref->errorCode = errorCode;
146 sendSignal(req->senderRef, GSN_ACC_SCANREF,
147 signal, AccScanRef::SignalLength, JBB);
166 Dbtux::execTUX_BOUND_INFO(
Signal* signal)
172 scanPtr.i = req->tuxScanPtrI;
173 c_scanOpPool.
getPtr(scanPtr);
174 ScanOp& scan = *scanPtr.p;
175 const Index&
index = *c_indexPool.
getPtr(scan.m_indexId);
176 const DescHead& descHead = getDescHead(index);
177 const KeyType* keyTypes = getKeyTypes(descHead);
179 const Uint32*
const boundData = &req->data[0];
180 Uint32 boundLen = req->boundAiLength;
181 Uint32 boundOffset = 0;
183 if (unlikely(scan.m_statOpPtrI != RNIL)) {
186 statPtr.i = scan.m_statOpPtrI;
187 c_statOpPool.
getPtr(statPtr);
189 if (statScanInit(statPtr, boundData, boundLen, &usedLen) == -1) {
191 ndbrequire(scan.m_errorCode != 0);
192 req->errorCode = scan.m_errorCode;
195 ndbrequire(usedLen <= boundLen);
197 boundOffset += usedLen;
200 for (
unsigned idir = 0; idir <= 1; idir++) {
207 BoundInfo boundInfo[MaxIndexAttributes];
209 Uint32 maxAttrId = 0;
210 const Uint32*
const data = &boundData[boundOffset];
212 while (offset + 2 <= boundLen) {
217 const Uint32 byteSize = ah->getByteSize();
218 const Uint32 dataSize = ah->getDataSize();
220 if (unlikely(type > 4)) {
222 scan.m_errorCode = TuxBoundInfo::InvalidAttrInfo;
223 req->errorCode = scan.m_errorCode;
232 if ((type2 & 0x2) == (idir << 1)) {
233 if (unlikely(attrId >= index.m_numAttrs)) {
235 scan.m_errorCode = TuxBoundInfo::InvalidAttrInfo;
236 req->errorCode = scan.m_errorCode;
240 while (maxAttrId <= attrId) {
242 BoundInfo& b = boundInfo[maxAttrId];
246 BoundInfo& b = boundInfo[attrId];
248 if (unlikely(b.type2 != -1)) {
250 scan.m_errorCode = TuxBoundInfo::InvalidBounds;
251 req->errorCode = scan.m_errorCode;
254 b.type2 = (int)type2;
255 b.offset = offset + 1;
259 offset += 2 + dataSize;
261 if (unlikely(offset != boundLen)) {
263 scan.m_errorCode = TuxBoundInfo::InvalidAttrInfo;
264 req->errorCode = scan.m_errorCode;
268 KeyData searchBoundData(index.m_keySpec,
true, 0);
269 KeyBound searchBound(searchBoundData);
270 searchBoundData.set_buf(c_ctx.c_searchKey, MaxAttrDataSize << 2);
273 for (i = 0; i < maxAttrId; i++) {
275 const BoundInfo& b = boundInfo[
i];
277 strict = (b.type2 & 0x1);
278 if (unlikely(b.type2 == -1 || (i + 1 < maxAttrId && strict))) {
280 scan.m_errorCode = TuxBoundInfo::InvalidBounds;
281 req->errorCode = scan.m_errorCode;
285 if (unlikely(searchBoundData.add_poai(&data[b.offset], &len) == -1 ||
288 scan.m_errorCode = TuxBoundInfo::InvalidCharFormat;
289 req->errorCode = scan.m_errorCode;
294 if (maxAttrId != 0) {
297 side = (-1) * (1 - 2 * strict) * (1 - 2 * int(idir));
299 if (unlikely(searchBound.finalize(side) == -1)) {
301 scan.m_errorCode = TuxBoundInfo::InvalidCharFormat;
302 req->errorCode = scan.m_errorCode;
305 ScanBound& scanBound = scan.m_scanBound[idir];
306 scanBound.m_cnt = maxAttrId;
307 scanBound.m_side = side;
312 const Uint32* data = (
const Uint32*)searchBoundData.get_data_buf();
313 Uint32
size = (searchBoundData.get_data_len() + 3) / 4;
314 bool ok = b.append(data, size);
317 scan.m_errorCode = TuxBoundInfo::OutOfBuffers;
318 req->errorCode = scan.m_errorCode;
323 if (ERROR_INSERTED(12009)) {
325 CLEAR_ERROR_INSERT_VALUE;
326 scan.m_errorCode = TuxBoundInfo::InvalidBounds;
327 req->errorCode = scan.m_errorCode;
335 Dbtux::execNEXT_SCANREQ(
Signal* signal)
341 scanPtr.i = req->accPtr;
342 c_scanOpPool.
getPtr(scanPtr);
343 ScanOp& scan = *scanPtr.p;
344 Frag& frag = *c_fragPool.
getPtr(scan.m_fragPtrI);
346 if (debugFlags & DebugScan) {
347 debugOut <<
"NEXT_SCANREQ scan " << scanPtr.i <<
" " << scan << endl;
351 switch (req->scanFlag) {
352 case NextScanReq::ZSCAN_NEXT:
355 case NextScanReq::ZSCAN_NEXT_COMMIT:
357 case NextScanReq::ZSCAN_COMMIT:
359 if (! scan.m_readCommitted) {
362 lockReq->returnCode = RNIL;
363 lockReq->requestInfo = AccLockReq::Unlock;
364 lockReq->accOpPtr = req->accOperationPtr;
365 EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
367 ndbrequire(lockReq->returnCode == AccLockReq::Success);
368 removeAccLockOp(scanPtr, req->accOperationPtr);
370 if (req->scanFlag == NextScanReq::ZSCAN_COMMIT) {
373 conf->scanPtr = scan.m_userPtr;
374 unsigned signalLength = 1;
375 sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
376 signal, signalLength, JBB);
380 case NextScanReq::ZSCAN_CLOSE:
383 if (scan.m_scanPos.m_loc != NullTupLoc) {
385 const TupLoc loc = scan.m_scanPos.m_loc;
386 NodeHandle node(frag);
387 selectNode(node, loc);
388 unlinkScan(node, scanPtr);
389 scan.m_scanPos.m_loc = NullTupLoc;
391 if (scan.m_lockwait) {
393 ndbrequire(scan.m_accLockOp != RNIL);
396 lockReq->returnCode = RNIL;
397 lockReq->requestInfo = AccLockReq::AbortWithConf;
398 lockReq->accOpPtr = scan.m_accLockOp;
400 AccLockReq::UndoSignalLength);
402 ndbrequire(lockReq->returnCode == AccLockReq::Success);
403 scan.m_state = ScanOp::Aborting;
406 if (scan.m_state == ScanOp::Locked) {
408 ndbrequire(scan.m_accLockOp != RNIL);
410 lockReq->returnCode = RNIL;
411 lockReq->requestInfo = AccLockReq::Abort;
412 lockReq->accOpPtr = scan.m_accLockOp;
414 AccLockReq::UndoSignalLength);
416 ndbrequire(lockReq->returnCode == AccLockReq::Success);
417 scan.m_accLockOp = RNIL;
419 scan.m_state = ScanOp::Aborting;
420 scanClose(signal, scanPtr);
422 case NextScanReq::ZSCAN_NEXT_ABORT:
431 checkReq->accPtr = scanPtr.i;
432 checkReq->checkLcpStop = AccCheckScan::ZNOT_CHECK_LCP_STOP;
433 EXECUTE_DIRECT(DBTUX, GSN_ACC_CHECK_SCAN, signal, AccCheckScan::SignalLength);
438 Dbtux::execACC_CHECK_SCAN(
Signal* signal)
444 scanPtr.i = req->accPtr;
445 c_scanOpPool.
getPtr(scanPtr);
446 ScanOp& scan = *scanPtr.p;
447 Frag& frag = *c_fragPool.
getPtr(scan.m_fragPtrI);
449 if (debugFlags & DebugScan) {
450 debugOut <<
"ACC_CHECK_SCAN scan " << scanPtr.i <<
" " << scan << endl;
453 if (req->checkLcpStop == AccCheckScan::ZCHECK_LCP_STOP) {
455 signal->theData[0] = scan.m_userPtr;
456 signal->theData[1] =
true;
461 if (scan.m_lockwait) {
464 const TreeEnt ent = scan.m_scanEnt;
466 conf->scanPtr = scan.m_userPtr;
467 conf->accOperationPtr = RNIL;
468 conf->fragId = frag.m_fragId;
469 unsigned signalLength = 3;
471 sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,
472 signal, signalLength, JBB);
476 const Index& index = *c_indexPool.
getPtr(frag.m_indexId);
477 if (unlikely(index.m_state != Index::Online) &&
478 scanPtr.p->m_errorCode == 0) {
481 if (debugFlags & (DebugMeta | DebugScan)) {
482 debugOut <<
"Index dropping at execACC_CHECK_SCAN " << scanPtr.i <<
" " << *scanPtr.p << endl;
485 scanPtr.p->m_errorCode = AccScanRef::TuxIndexNotOnline;
487 if (scan.m_state == ScanOp::First) {
492 if (scan.m_state == ScanOp::Current ||
493 scan.m_state == ScanOp::Next) {
499 Uint32* pkData = c_ctx.c_dataBuffer;
501 if (scan.m_state == ScanOp::Found) {
504 ndbrequire(scan.m_accLockOp == RNIL);
505 if (! scan.m_readCommitted) {
507 const TreeEnt ent = scan.m_scanEnt;
509 readTablePk(frag, ent, pkData, pkSize);
512 lockReq->returnCode = RNIL;
513 lockReq->requestInfo =
514 scan.m_lockMode == 0 ? AccLockReq::LockShared : AccLockReq::LockExclusive;
515 lockReq->accOpPtr = RNIL;
516 lockReq->userPtr = scanPtr.i;
517 lockReq->userRef = reference();
518 lockReq->tableId = scan.m_tableId;
519 lockReq->fragId = frag.m_fragId;
520 lockReq->fragPtrI = frag.m_accTableFragPtrI;
521 const Uint32*
const buf32 =
static_cast<Uint32*
>(pkData);
522 const Uint64*
const buf64 =
reinterpret_cast<const Uint64*
>(buf32);
523 lockReq->hashValue = md5_hash(buf64, pkSize);
525 getTupAddr(frag, ent, lkey1, lkey2);
526 lockReq->page_id = lkey1;
527 lockReq->page_idx = lkey2;
528 lockReq->transId1 = scan.m_transId1;
529 lockReq->transId2 = scan.m_transId2;
531 EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::LockSignalLength);
533 switch (lockReq->returnCode) {
534 case AccLockReq::Success:
536 scan.m_state = ScanOp::Locked;
537 scan.m_accLockOp = lockReq->accOpPtr;
539 if (debugFlags & (DebugScan | DebugLock)) {
540 debugOut <<
"Lock immediate scan " << scanPtr.i <<
" " << scan << endl;
544 case AccLockReq::IsBlocked:
547 scan.m_state = ScanOp::Blocked;
548 scan.m_lockwait =
true;
549 scan.m_accLockOp = lockReq->accOpPtr;
551 if (debugFlags & (DebugScan | DebugLock)) {
552 debugOut <<
"Lock wait scan " << scanPtr.i <<
" " << scan << endl;
556 signal->theData[0] = scan.m_userPtr;
557 signal->theData[1] =
true;
562 case AccLockReq::Refused:
567 scan.m_state = ScanOp::Next;
568 signal->theData[0] = scan.m_userPtr;
569 signal->theData[1] =
true;
574 case AccLockReq::NoFreeOp:
579 scan.m_state = ScanOp::Found;
580 signal->theData[0] = scan.m_userPtr;
581 signal->theData[1] =
true;
591 scan.m_state = ScanOp::Locked;
594 if (scan.m_state == ScanOp::Locked) {
598 const TreeEnt ent = scan.m_scanEnt;
601 conf->scanPtr = scan.m_userPtr;
603 Uint32 accLockOp = scan.m_accLockOp;
604 if (accLockOp != RNIL) {
605 scan.m_accLockOp = RNIL;
607 addAccLockOp(scanPtr, accLockOp);
609 ndbrequire(scan.m_readCommitted);
611 accLockOp = (Uint32)-1;
613 conf->accOperationPtr = accLockOp;
614 conf->fragId = frag.m_fragId;
616 getTupAddr(frag, ent, lkey1, lkey2);
617 conf->localKey[0] = lkey1;
618 conf->localKey[1] = lkey2;
619 unsigned signalLength = 5;
621 if (! scan.m_readCommitted) {
622 sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,
623 signal, signalLength, JBB);
625 Uint32 blockNo = refToMain(scan.m_userRef);
629 scan.m_state = ScanOp::Next;
633 if (scan.m_state == ScanOp::Last) {
636 conf->scanPtr = scan.m_userPtr;
637 conf->accOperationPtr = RNIL;
639 unsigned signalLength = 3;
640 sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
641 signal, signalLength, JBB);
654 Dbtux::execACCKEYCONF(
Signal* signal)
658 scanPtr.i = signal->theData[0];
659 c_scanOpPool.
getPtr(scanPtr);
660 ScanOp& scan = *scanPtr.p;
662 if (debugFlags & (DebugScan | DebugLock)) {
663 debugOut <<
"Lock obtained scan " << scanPtr.i <<
" " << scan << endl;
666 ndbrequire(scan.m_lockwait && scan.m_accLockOp != RNIL);
667 scan.m_lockwait =
false;
668 if (scan.m_state == ScanOp::Blocked) {
671 scan.m_state = ScanOp::Locked;
675 if (scan.m_state != ScanOp::Aborting) {
679 lockReq->returnCode = RNIL;
680 lockReq->requestInfo = AccLockReq::Abort;
681 lockReq->accOpPtr = scan.m_accLockOp;
682 EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
684 ndbrequire(lockReq->returnCode == AccLockReq::Success);
685 scan.m_accLockOp = RNIL;
690 scan.m_accLockOp = RNIL;
699 Dbtux::execACCKEYREF(
Signal* signal)
703 scanPtr.i = signal->theData[0];
704 c_scanOpPool.
getPtr(scanPtr);
705 ScanOp& scan = *scanPtr.p;
707 if (debugFlags & (DebugScan | DebugLock)) {
708 debugOut <<
"Lock refused scan " << scanPtr.i <<
" " << scan << endl;
711 ndbrequire(scan.m_lockwait && scan.m_accLockOp != RNIL);
712 scan.m_lockwait =
false;
713 if (scan.m_state != ScanOp::Aborting) {
717 lockReq->returnCode = RNIL;
718 lockReq->requestInfo = AccLockReq::Abort;
719 lockReq->accOpPtr = scan.m_accLockOp;
720 EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
722 ndbrequire(lockReq->returnCode == AccLockReq::Success);
723 scan.m_accLockOp = RNIL;
725 if (scan.m_state == ScanOp::Blocked) {
729 const Frag& frag = *c_fragPool.
getPtr(scan.m_fragPtrI);
730 const Index& index = *c_indexPool.
getPtr(frag.m_indexId);
731 ndbassert(index.m_state != Index::Online);
733 scan.m_state = ScanOp::Next;
739 scan.m_accLockOp = RNIL;
748 Dbtux::execACC_ABORTCONF(
Signal* signal)
752 scanPtr.i = signal->theData[0];
753 c_scanOpPool.
getPtr(scanPtr);
754 ScanOp& scan = *scanPtr.p;
756 if (debugFlags & (DebugScan | DebugLock)) {
757 debugOut <<
"ACC_ABORTCONF scan " << scanPtr.i <<
" " << scan << endl;
760 ndbrequire(scan.m_state == ScanOp::Aborting);
762 if (scan.m_lockwait) {
764 scan.m_lockwait =
false;
765 scan.m_accLockOp = RNIL;
767 scanClose(signal, scanPtr);
774 Dbtux::scanFirst(ScanOpPtr scanPtr)
776 ScanOp& scan = *scanPtr.p;
777 Frag& frag = *c_fragPool.
getPtr(scan.m_fragPtrI);
778 const Index& index = *c_indexPool.
getPtr(frag.m_indexId);
780 if (debugFlags & DebugScan) {
781 debugOut <<
"Enter first scan " << scanPtr.i <<
" " << scan << endl;
785 const unsigned idir = scan.m_descending;
787 const ScanBound& scanBound = scan.m_scanBound[idir];
788 KeyDataC searchBoundData(index.m_keySpec,
true);
789 KeyBoundC searchBound(searchBoundData);
790 unpackBound(c_ctx, scanBound, searchBound);
792 searchToScan(frag, idir, searchBound, treePos);
793 if (treePos.m_loc != NullTupLoc) {
794 scan.m_scanPos = treePos;
796 NodeHandle node(frag);
797 selectNode(node, treePos.m_loc);
798 linkScan(node, scanPtr);
799 if (treePos.m_dir == 3) {
802 TreeEnt ent = node.getEnt(treePos.m_pos);
803 if (scanCheck(scanPtr, ent)) {
805 scan.m_state = ScanOp::Current;
808 scan.m_state = ScanOp::Last;
812 scan.m_state = ScanOp::Next;
816 scan.m_state = ScanOp::Last;
819 if (debugFlags & DebugScan) {
820 debugOut <<
"Leave first scan " << scanPtr.i <<
" " << scan << endl;
829 Dbtux::scanFind(ScanOpPtr scanPtr)
831 ScanOp& scan = *scanPtr.p;
832 Frag& frag = *c_fragPool.
getPtr(scan.m_fragPtrI);
834 if (debugFlags & DebugScan) {
835 debugOut <<
"Enter find scan " << scanPtr.i <<
" " << scan << endl;
838 ndbrequire(scan.m_state == ScanOp::Current || scan.m_state == ScanOp::Next);
841 if (scan.m_state == ScanOp::Next)
842 scanNext(scanPtr,
false);
843 if (scan.m_state == ScanOp::Current) {
845 const TreePos pos = scan.m_scanPos;
846 NodeHandle node(frag);
847 selectNode(node, pos.m_loc);
848 const TreeEnt ent = node.getEnt(pos.m_pos);
849 if (unlikely(scan.m_statOpPtrI != RNIL)) {
851 statPtr.i = scan.m_statOpPtrI;
852 c_statOpPool.
getPtr(statPtr);
854 int ret = statScanAddRow(statPtr, ent);
857 scan.m_state = ScanOp::Found;
859 scan.m_scanEnt = ent;
862 }
else if (scanVisible(scanPtr, ent)) {
864 scan.m_state = ScanOp::Found;
865 scan.m_scanEnt = ent;
872 scan.m_state = ScanOp::Next;
875 if (debugFlags & DebugScan) {
876 debugOut <<
"Leave find scan " << scanPtr.i <<
" " << scan << endl;
904 Dbtux::scanNext(ScanOpPtr scanPtr,
bool fromMaintReq)
906 ScanOp& scan = *scanPtr.p;
907 Frag& frag = *c_fragPool.
getPtr(scan.m_fragPtrI);
909 if (debugFlags & (DebugMaint | DebugScan)) {
910 debugOut <<
"Enter next scan " << scanPtr.i <<
" " << scan << endl;
914 ndbrequire(scan.m_state != ScanOp::Locked);
916 const unsigned idir = scan.m_descending;
917 const int jdir = 1 - 2 * (int)idir;
919 TreePos pos = scan.m_scanPos;
921 NodeHandle origNode(frag);
922 selectNode(origNode, pos.m_loc);
923 ndbrequire(islinkScan(origNode, scanPtr));
925 NodeHandle node = origNode;
931 if (debugFlags & (DebugMaint | DebugScan)) {
932 debugOut <<
"Current scan " << scanPtr.i <<
" pos " << pos <<
" node " << node << endl;
935 if (pos.m_dir == 2) {
938 pos.m_loc = NullTupLoc;
941 if (node.m_loc != pos.m_loc) {
943 selectNode(node, pos.m_loc);
945 if (pos.m_dir == 4) {
948 TupLoc loc = node.getLink(idir);
949 if (loc != NullTupLoc) {
958 if (pos.m_dir == 5) {
961 TupLoc loc = node.getLink(1 - idir);
962 if (loc != NullTupLoc) {
969 pos.m_dir = 1 - idir;
971 const unsigned occup = node.getOccup();
974 ndbrequire(fromMaintReq);
976 pos.m_loc = node.getLink(2);
977 pos.m_dir = node.getSide();
980 if (pos.m_dir == idir) {
983 pos.m_pos = idir == 0 ? (Uint16)-1 : occup;
986 if (pos.m_dir == 3) {
991 if (pos.m_pos < occup) {
994 ent = node.getEnt(pos.m_pos);
995 if (! scanCheck(scanPtr, ent)) {
997 pos.m_loc = NullTupLoc;
1005 if (pos.m_dir == 1 - idir) {
1008 pos.m_loc = node.getLink(2);
1009 pos.m_dir = node.getSide();
1015 scan.m_scanPos = pos;
1017 if (pos.m_loc != NullTupLoc) {
1018 ndbrequire(pos.m_dir == 3);
1019 ndbrequire(pos.m_loc == node.m_loc);
1020 if (origNode.m_loc != node.m_loc) {
1022 unlinkScan(origNode, scanPtr);
1023 linkScan(node, scanPtr);
1025 if (scan.m_state != ScanOp::Blocked) {
1026 scan.m_state = ScanOp::Current;
1029 ndbrequire(fromMaintReq);
1030 TreeEnt& scanEnt = scan.m_scanEnt;
1031 ndbrequire(scanEnt.m_tupLoc != NullTupLoc);
1032 if (scanEnt.eqtuple(ent)) {
1037 scanEnt.m_tupLoc = NullTupLoc;
1038 scan.m_state = ScanOp::Current;
1043 unlinkScan(origNode, scanPtr);
1044 scan.m_state = ScanOp::Last;
1047 if (debugFlags & (DebugMaint | DebugScan)) {
1048 debugOut <<
"Leave next scan " << scanPtr.i <<
" " << scan << endl;
1061 Dbtux::scanCheck(ScanOpPtr scanPtr, TreeEnt ent)
1063 ScanOp& scan = *scanPtr.p;
1064 if (unlikely(scan.m_errorCode != 0)) {
1068 Frag& frag = *c_fragPool.
getPtr(scan.m_fragPtrI);
1069 const Index& index = *c_indexPool.
getPtr(frag.m_indexId);
1070 const unsigned idir = scan.m_descending;
1071 const int jdir = 1 - 2 * (int)idir;
1072 const ScanBound& scanBound = scan.m_scanBound[1 - idir];
1074 if (scanBound.m_cnt != 0) {
1077 KeyDataC searchBoundData(index.m_keySpec,
true);
1078 KeyBoundC searchBound(searchBoundData);
1079 unpackBound(c_ctx, scanBound, searchBound);
1081 KeyData entryKey(index.m_keySpec,
true, 0);
1082 entryKey.set_buf(c_ctx.c_entryKey, MaxAttrDataSize << 2);
1083 readKeyAttrs(c_ctx, frag, ent, entryKey, index.m_numAttrs);
1085 const Uint32 boundCount = searchBound.get_data().get_cnt();
1086 ret = cmpSearchBound(c_ctx, searchBound, entryKey, boundCount);
1087 ndbrequire(ret != 0);
1092 if (debugFlags & DebugScan) {
1093 debugOut <<
"Check scan " << scanPtr.i <<
" " << scan <<
" ret:" << dec << ret << endl;
1111 Dbtux::scanVisible(ScanOpPtr scanPtr, TreeEnt ent)
1113 const ScanOp& scan = *scanPtr.p;
1114 if (unlikely(scan.m_errorCode != 0)) {
1118 const Frag& frag = *c_fragPool.
getPtr(scan.m_fragPtrI);
1119 Uint32 tableFragPtrI = frag.m_tupTableFragPtrI;
1120 Uint32 pageId = ent.m_tupLoc.getPageId();
1121 Uint32 pageOffset = ent.m_tupLoc.getPageOffset();
1122 Uint32 tupVersion = ent.m_tupVersion;
1124 if (scan.m_scanEnt.m_tupLoc == ent.m_tupLoc)
1129 Uint32 transId1 = scan.m_transId1;
1130 Uint32 transId2 = scan.m_transId2;
1131 bool dirty = scan.m_readCommitted;
1132 Uint32 savePointId = scan.m_savePointId;
1133 bool ret = c_tup->tuxQueryTh(tableFragPtrI, pageId, pageOffset, tupVersion, transId1, transId2, dirty, savePointId);
1146 Dbtux::scanClose(
Signal* signal, ScanOpPtr scanPtr)
1148 ScanOp& scan = *scanPtr.p;
1149 ndbrequire(! scan.m_lockwait && scan.m_accLockOp == RNIL);
1151 if (! scan.m_accLockOps.isEmpty()) {
1153 abortAccLockOps(signal, scanPtr);
1155 if (scanPtr.p->m_errorCode == 0) {
1159 conf->scanPtr = scanPtr.p->m_userPtr;
1160 conf->accOperationPtr = RNIL;
1161 conf->fragId = RNIL;
1162 unsigned signalLength = 3;
1163 sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
1164 signal, signalLength, JBB);
1168 ref->scanPtr = scanPtr.p->m_userPtr;
1169 ref->accOperationPtr = RNIL;
1171 ref->errorCode = scanPtr.p->m_errorCode;
1172 sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANREF,
1173 signal, NextScanRef::SignalLength, JBB);
1175 releaseScanOp(scanPtr);
1179 Dbtux::abortAccLockOps(
Signal* signal, ScanOpPtr scanPtr)
1181 ScanOp& scan = *scanPtr.p;
1183 if (debugFlags & (DebugScan | DebugLock)) {
1184 debugOut <<
"Abort locks in scan " << scanPtr.i <<
" " << scan << endl;
1188 ScanLockPtr lockPtr;
1189 while (list.first(lockPtr)) {
1192 lockReq->returnCode = RNIL;
1193 lockReq->requestInfo = AccLockReq::Abort;
1194 lockReq->accOpPtr = lockPtr.p->m_accLockOp;
1195 EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
1197 ndbrequire(lockReq->returnCode == AccLockReq::Success);
1198 list.release(lockPtr);
1203 Dbtux::addAccLockOp(ScanOpPtr scanPtr, Uint32 accLockOp)
1205 ScanOp& scan = *scanPtr.p;
1207 if (debugFlags & (DebugScan | DebugLock)) {
1208 debugOut <<
"Add lock " << hex << accLockOp << dec
1209 <<
" to scan " << scanPtr.i <<
" " << scan << endl;
1213 ScanLockPtr lockPtr;
1215 list.first(lockPtr);
1216 while (lockPtr.i != RNIL) {
1217 ndbrequire(lockPtr.p->m_accLockOp != accLockOp);
1221 bool ok = list.seize(lockPtr);
1223 ndbrequire(accLockOp != RNIL);
1224 lockPtr.p->m_accLockOp = accLockOp;
1228 Dbtux::removeAccLockOp(ScanOpPtr scanPtr, Uint32 accLockOp)
1230 ScanOp& scan = *scanPtr.p;
1232 if (debugFlags & (DebugScan | DebugLock)) {
1233 debugOut <<
"Remove lock " << hex << accLockOp << dec
1234 <<
" from scan " << scanPtr.i <<
" " << scan << endl;
1238 ScanLockPtr lockPtr;
1239 list.first(lockPtr);
1240 while (lockPtr.i != RNIL) {
1241 if (lockPtr.p->m_accLockOp == accLockOp) {
1247 ndbrequire(lockPtr.i != RNIL);
1248 list.release(lockPtr);
1255 Dbtux::releaseScanOp(ScanOpPtr& scanPtr)
1258 if (debugFlags & DebugScan) {
1259 debugOut <<
"Release scan " << scanPtr.i <<
" " << *scanPtr.p << endl;
1262 Frag& frag = *c_fragPool.
getPtr(scanPtr.p->m_fragPtrI);
1263 for (
unsigned i = 0; i <= 1; i++) {
1264 ScanBound& scanBound = scanPtr.p->m_scanBound[
i];
1269 if (unlikely(scanPtr.p->m_statOpPtrI != RNIL)) {
1272 statPtr.i = scanPtr.p->m_statOpPtrI;
1273 c_statOpPool.
getPtr(statPtr);
1274 c_statOpPool.
release(statPtr);
1277 frag.m_scanList.release(scanPtr);