19 #define DBTUP_SCAN_CPP
21 #include <signaldata/AccScan.hpp>
22 #include <signaldata/NextScan.hpp>
23 #include <signaldata/AccLock.hpp>
24 #include <md5_hash.hpp>
28 #define jam() { jamLine(32000 + __LINE__); }
29 #define jamEntry() { jamEntryLine(32000 + __LINE__); }
32 #define dbg(x) globalSignalLoggers.log x
38 Dbtup::execACC_SCANREQ(
Signal* signal)
48 tablePtr.i = req->tableId;
49 ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
50 FragrecordPtr fragPtr;
51 Uint32 fragId = req->fragmentNo;
53 getFragmentrec(fragPtr, fragId, tablePtr.p);
54 ndbrequire(fragPtr.i != RNIL);
55 Fragrecord& frag = *fragPtr.p;
59 if (AccScanReq::getLcpScanFlag(req->requestInfo))
62 bits |= ScanOp::SCAN_LCP;
63 c_scanOpPool.
getPtr(scanPtr, c_lcp_scan_op);
64 ndbrequire(scanPtr.p->m_fragPtrI == fragPtr.i);
65 ndbrequire(scanPtr.p->m_state == ScanOp::First);
71 if (! list.seize(scanPtr)) {
75 new (scanPtr.p) ScanOp;
78 if (!AccScanReq::getNoDiskScanFlag(req->requestInfo)
79 && tablePtr.p->m_no_of_disk_attributes)
81 bits |= ScanOp::SCAN_DD;
84 bool mm = (bits & ScanOp::SCAN_DD);
85 if ((tablePtr.p->m_attributes[mm].m_no_of_varsize +
86 tablePtr.p->m_attributes[mm].m_no_of_dynamic) > 0)
88 if (bits & ScanOp::SCAN_DD)
92 bits |= ScanOp::SCAN_VS;
96 if (! AccScanReq::getReadCommittedFlag(req->requestInfo))
98 if (AccScanReq::getLockMode(req->requestInfo) == 0)
99 bits |= ScanOp::SCAN_LOCK_SH;
101 bits |= ScanOp::SCAN_LOCK_EX;
104 if (AccScanReq::getNRScanFlag(req->requestInfo))
107 bits |= ScanOp::SCAN_NR;
108 scanPtr.p->m_endPage = req->maxPage;
109 if (req->maxPage != RNIL && req->maxPage > frag.m_max_page_no)
111 ndbout_c(
"%u %u endPage: %u (noOfPages: %u maxPage: %u)",
113 req->maxPage, fragPtr.p->noOfPages,
114 fragPtr.p->m_max_page_no);
120 scanPtr.p->m_endPage = RNIL;
123 if (AccScanReq::getLcpScanFlag(req->requestInfo))
126 ndbrequire((bits & ScanOp::SCAN_DD) == 0);
127 ndbrequire((bits & ScanOp::SCAN_LOCK) == 0);
130 if (bits & ScanOp::SCAN_VS)
132 ndbrequire((bits & ScanOp::SCAN_NR) == 0);
133 ndbrequire((bits & ScanOp::SCAN_LCP) == 0);
137 ScanOp& scan = *scanPtr.p;
138 scan.m_state = ScanOp::First;
140 scan.m_userPtr = req->senderData;
141 scan.m_userRef = req->senderRef;
142 scan.m_tableId = tablePtr.i;
143 scan.m_fragId = frag.fragmentId;
144 scan.m_fragPtrI = fragPtr.i;
145 scan.m_transId1 = req->transId1;
146 scan.m_transId2 = req->transId2;
147 scan.m_savePointId = req->savePointId;
151 conf->scanPtr = req->senderData;
152 conf->accPtr = scanPtr.i;
153 conf->flag = AccScanConf::ZNOT_EMPTY_FRAGMENT;
154 sendSignal(req->senderRef, GSN_ACC_SCANCONF,
155 signal, AccScanConf::SignalLength, JBB);
158 if (scanPtr.i != RNIL) {
160 releaseScanOp(scanPtr);
163 signal->theData[0] = 0x313;
164 sendSignal(req->senderRef, GSN_ACC_SCANREF, signal, 1, JBB);
168 Dbtup::execNEXT_SCANREQ(
Signal* signal)
174 c_scanOpPool.
getPtr(scanPtr, req->accPtr);
175 ScanOp& scan = *scanPtr.p;
176 switch (req->scanFlag) {
177 case NextScanReq::ZSCAN_NEXT:
180 case NextScanReq::ZSCAN_NEXT_COMMIT:
182 case NextScanReq::ZSCAN_COMMIT:
184 if ((scan.m_bits & ScanOp::SCAN_LOCK) != 0) {
187 lockReq->returnCode = RNIL;
188 lockReq->requestInfo = AccLockReq::Unlock;
189 lockReq->accOpPtr = req->accOperationPtr;
191 signal, AccLockReq::UndoSignalLength);
193 ndbrequire(lockReq->returnCode == AccLockReq::Success);
194 removeAccLockOp(scan, req->accOperationPtr);
196 if (req->scanFlag == NextScanReq::ZSCAN_COMMIT) {
198 conf->scanPtr = scan.m_userPtr;
199 unsigned signalLength = 1;
200 sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
201 signal, signalLength, JBB);
205 case NextScanReq::ZSCAN_CLOSE:
207 if (scan.m_bits & ScanOp::SCAN_LOCK_WAIT) {
209 ndbrequire(scan.m_accLockOp != RNIL);
212 lockReq->returnCode = RNIL;
213 lockReq->requestInfo = AccLockReq::AbortWithConf;
214 lockReq->accOpPtr = scan.m_accLockOp;
216 signal, AccLockReq::UndoSignalLength);
218 ndbrequire(lockReq->returnCode == AccLockReq::Success);
219 scan.m_state = ScanOp::Aborting;
222 if (scan.m_state == ScanOp::Locked) {
224 ndbrequire(scan.m_accLockOp != RNIL);
226 lockReq->returnCode = RNIL;
227 lockReq->requestInfo = AccLockReq::Abort;
228 lockReq->accOpPtr = scan.m_accLockOp;
230 signal, AccLockReq::UndoSignalLength);
232 ndbrequire(lockReq->returnCode == AccLockReq::Success);
233 scan.m_accLockOp = RNIL;
235 scan.m_state = ScanOp::Aborting;
236 scanClose(signal, scanPtr);
238 case NextScanReq::ZSCAN_NEXT_ABORT:
247 checkReq->accPtr = scanPtr.i;
248 checkReq->checkLcpStop = AccCheckScan::ZNOT_CHECK_LCP_STOP;
249 EXECUTE_DIRECT(DBTUP, GSN_ACC_CHECK_SCAN, signal, AccCheckScan::SignalLength);
254 Dbtup::execACC_CHECK_SCAN(
Signal* signal)
260 c_scanOpPool.
getPtr(scanPtr, req->accPtr);
261 ScanOp& scan = *scanPtr.p;
263 FragrecordPtr fragPtr;
264 fragPtr.i = scan.m_fragPtrI;
265 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
266 Fragrecord& frag = *fragPtr.p;
267 if (req->checkLcpStop == AccCheckScan::ZCHECK_LCP_STOP) {
269 signal->theData[0] = scan.m_userPtr;
270 signal->theData[1] =
true;
275 if (scan.m_bits & ScanOp::SCAN_LOCK_WAIT) {
279 conf->scanPtr = scan.m_userPtr;
280 conf->accOperationPtr = RNIL;
281 conf->fragId = frag.fragmentId;
282 unsigned signalLength = 3;
284 sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,
285 signal, signalLength, JBB);
289 const bool lcp = (scan.m_bits & ScanOp::SCAN_LCP);
291 if (lcp && ! fragPtr.p->m_lcp_keep_list_head.isNull())
299 handle_lcp_keep(signal, fragPtr.p, scanPtr.p);
303 if (scan.m_state == ScanOp::First) {
305 scanFirst(signal, scanPtr);
307 if (scan.m_state == ScanOp::Next) {
309 bool immediate =
scanNext(signal, scanPtr);
316 scanReply(signal, scanPtr);
320 Dbtup::scanReply(
Signal* signal, ScanOpPtr scanPtr)
322 ScanOp& scan = *scanPtr.p;
323 FragrecordPtr fragPtr;
324 fragPtr.i = scan.m_fragPtrI;
325 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
326 Fragrecord& frag = *fragPtr.p;
328 Uint32* pkData = (Uint32*)c_dataBuffer;
330 if (scan.m_state == ScanOp::Current) {
333 ndbrequire(scan.m_accLockOp == RNIL);
334 if (scan.m_bits & ScanOp::SCAN_LOCK) {
337 const ScanPos& pos = scan.m_scanPos;
339 int ret = tuxReadPk(fragPtr.i, pos.m_realpid_mm, key_mm.m_page_idx,
343 dbg((DBTUP,
"PK size=%d data=%08x", pkSize, pkData[0]));
346 lockReq->returnCode = RNIL;
347 lockReq->requestInfo = (scan.m_bits & ScanOp::SCAN_LOCK_SH) ?
348 AccLockReq::LockShared : AccLockReq::LockExclusive;
349 lockReq->accOpPtr = RNIL;
350 lockReq->userPtr = scanPtr.i;
351 lockReq->userRef = reference();
352 lockReq->tableId = scan.m_tableId;
353 lockReq->fragId = frag.fragmentId;
354 lockReq->fragPtrI = RNIL;
355 lockReq->hashValue = md5_hash((Uint64*)pkData, pkSize);
356 lockReq->page_id = key_mm.m_page_no;
357 lockReq->page_idx = key_mm.m_page_idx;
358 lockReq->transId1 = scan.m_transId1;
359 lockReq->transId2 = scan.m_transId2;
361 signal, AccLockReq::LockSignalLength);
363 switch (lockReq->returnCode) {
364 case AccLockReq::Success:
366 scan.m_state = ScanOp::Locked;
367 scan.m_accLockOp = lockReq->accOpPtr;
369 case AccLockReq::IsBlocked:
372 scan.m_state = ScanOp::Blocked;
373 scan.m_bits |= ScanOp::SCAN_LOCK_WAIT;
374 scan.m_accLockOp = lockReq->accOpPtr;
376 signal->theData[0] = scan.m_userPtr;
377 signal->theData[1] =
true;
382 case AccLockReq::Refused:
387 scan.m_state = ScanOp::Next;
388 signal->theData[0] = scan.m_userPtr;
389 signal->theData[1] =
true;
394 case AccLockReq::NoFreeOp:
399 scan.m_state = ScanOp::Current;
400 signal->theData[0] = scan.m_userPtr;
401 signal->theData[1] =
true;
411 scan.m_state = ScanOp::Locked;
415 if (scan.m_state == ScanOp::Locked) {
420 conf->scanPtr = scan.m_userPtr;
422 Uint32 accLockOp = scan.m_accLockOp;
423 if (accLockOp != RNIL) {
424 scan.m_accLockOp = RNIL;
426 addAccLockOp(scan, accLockOp);
428 ndbrequire(! (scan.m_bits & ScanOp::SCAN_LOCK));
430 accLockOp = (Uint32)-1;
432 const ScanPos& pos = scan.m_scanPos;
433 conf->accOperationPtr = accLockOp;
434 conf->fragId = frag.fragmentId;
435 conf->localKey[0] = pos.m_key_mm.m_page_no;
436 conf->localKey[1] = pos.m_key_mm.m_page_idx;
437 unsigned signalLength = 5;
438 if (scan.m_bits & ScanOp::SCAN_LOCK) {
439 sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,
440 signal, signalLength, JBB);
442 Uint32 blockNo = refToMain(scan.m_userRef);
447 scan.m_state = ScanOp::Next;
450 if (scan.m_state == ScanOp::Last ||
451 scan.m_state == ScanOp::Invalid) {
454 conf->scanPtr = scan.m_userPtr;
455 conf->accOperationPtr = RNIL;
457 unsigned signalLength = 3;
458 sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
459 signal, signalLength, JBB);
472 Dbtup::execACCKEYCONF(
Signal* signal)
476 scanPtr.i = signal->theData[0];
478 Uint32 localKey1 = signal->theData[3];
479 Uint32 localKey2 = signal->theData[4];
481 tmp.m_page_no = localKey1;
482 tmp.m_page_idx = localKey2;
484 c_scanOpPool.
getPtr(scanPtr);
485 ScanOp& scan = *scanPtr.p;
486 ndbrequire(scan.m_bits & ScanOp::SCAN_LOCK_WAIT && scan.m_accLockOp != RNIL);
487 scan.m_bits &= ~ ScanOp::SCAN_LOCK_WAIT;
488 if (scan.m_state == ScanOp::Blocked) {
492 if (likely(scan.m_scanPos.m_key_mm.m_page_no == tmp.m_page_no &&
493 scan.m_scanPos.m_key_mm.m_page_idx == tmp.m_page_idx))
496 scan.m_state = ScanOp::Locked;
513 ndbout <<
"execACCKEYCONF "
514 << scan.m_scanPos.m_key_mm
515 <<
" != " << tmp <<
" ";
516 scan.m_bits |= ScanOp::SCAN_LOCK_WAIT;
517 execACCKEYREF(signal);
522 if (scan.m_state != ScanOp::Aborting) {
526 lockReq->returnCode = RNIL;
527 lockReq->requestInfo = AccLockReq::Abort;
528 lockReq->accOpPtr = scan.m_accLockOp;
529 EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
531 ndbrequire(lockReq->returnCode == AccLockReq::Success);
532 scan.m_accLockOp = RNIL;
537 scan.m_accLockOp = RNIL;
546 Dbtup::execACCKEYREF(
Signal* signal)
550 scanPtr.i = signal->theData[0];
551 c_scanOpPool.
getPtr(scanPtr);
552 ScanOp& scan = *scanPtr.p;
553 ndbrequire(scan.m_bits & ScanOp::SCAN_LOCK_WAIT && scan.m_accLockOp != RNIL);
554 scan.m_bits &= ~ ScanOp::SCAN_LOCK_WAIT;
555 if (scan.m_state != ScanOp::Aborting) {
559 lockReq->returnCode = RNIL;
560 lockReq->requestInfo = AccLockReq::Abort;
561 lockReq->accOpPtr = scan.m_accLockOp;
562 EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
564 ndbrequire(lockReq->returnCode == AccLockReq::Success);
565 scan.m_accLockOp = RNIL;
567 if (scan.m_state == ScanOp::Blocked) {
570 if (scan.m_bits & ScanOp::SCAN_NR)
573 scan.m_state = ScanOp::Next;
574 scan.m_scanPos.m_get = ScanPos::Get_tuple;
575 ndbout_c(
"Ignoring scan.m_state == ScanOp::Blocked, refetch");
580 scan.m_state = ScanOp::Next;
581 ndbout_c(
"Ignoring scan.m_state == ScanOp::Blocked");
588 scan.m_accLockOp = RNIL;
597 Dbtup::execACC_ABORTCONF(
Signal* signal)
601 scanPtr.i = signal->theData[0];
602 c_scanOpPool.
getPtr(scanPtr);
603 ScanOp& scan = *scanPtr.p;
604 ndbrequire(scan.m_state == ScanOp::Aborting);
606 if (scan.m_bits & ScanOp::SCAN_LOCK_WAIT) {
608 scan.m_bits &= ~ ScanOp::SCAN_LOCK_WAIT;
609 scan.m_accLockOp = RNIL;
611 scanClose(signal, scanPtr);
615 Dbtup::scanFirst(
Signal*, ScanOpPtr scanPtr)
617 ScanOp& scan = *scanPtr.p;
618 ScanPos& pos = scan.m_scanPos;
620 const Uint32 bits = scan.m_bits;
622 FragrecordPtr fragPtr;
623 fragPtr.i = scan.m_fragPtrI;
624 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
625 Fragrecord& frag = *fragPtr.p;
627 if (bits & ScanOp::SCAN_NR)
629 if (scan.m_endPage == 0 && frag.m_max_page_no == 0)
632 scan.m_state = ScanOp::Last;
636 else if (frag.noOfPages == 0)
639 scan.m_state = ScanOp::Last;
643 if (! (bits & ScanOp::SCAN_DD)) {
644 key.m_file_no = ZNIL;
646 pos.m_get = ScanPos::Get_page_mm;
648 pos.m_realpid_mm = RNIL;
650 Disk_alloc_info& alloc = frag.m_disk_alloc_info;
652 if (alloc.m_extent_list.firstItem == RNIL) {
654 scan.m_state = ScanOp::Last;
657 pos.m_extent_info_ptr_i = alloc.m_extent_list.firstItem;
658 Extent_info* ext = c_extent_pool.
getPtr(pos.m_extent_info_ptr_i);
659 key.m_file_no = ext->m_key.m_file_no;
660 key.m_page_no = ext->m_first_page_no;
661 pos.m_get = ScanPos::Get_page_dd;
663 key.m_page_idx = ((bits & ScanOp::SCAN_VS) == 0) ? 0 : 1;
665 scan.m_state = ScanOp::Next;
671 ScanOp& scan = *scanPtr.p;
674 const Uint32 bits = scan.m_bits;
677 tablePtr.i = scan.m_tableId;
678 ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
682 fragPtr.i = scan.m_fragPtrI;
683 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
688 Uint32 loop_count = 0;
689 Uint32 scanGCI = scanPtr.p->m_scanGCI;
692 const bool mm = (bits & ScanOp::SCAN_DD);
693 const bool lcp = (bits & ScanOp::SCAN_LCP);
695 const Uint32
size = ((bits & ScanOp::SCAN_VS) == 0) ?
696 table.m_offsets[mm].m_fix_header_size : 1;
697 const Uint32 first = ((bits & ScanOp::SCAN_VS) == 0) ? 0 : 1;
699 if (lcp && ! fragPtr.p->m_lcp_keep_list_head.isNull())
705 handle_lcp_keep(signal, fragPtr.p, scanPtr.p);
710 case ScanPos::Get_next_tuple:
712 key.m_page_idx +=
size;
714 case ScanPos::Get_tuple:
719 pos.m_get = ScanPos::Get_page;
720 pos.m_realpid_mm = RNIL;
728 case ScanPos::Get_next_page:
732 if (! (bits & ScanOp::SCAN_DD))
733 pos.m_get = ScanPos::Get_next_page_mm;
735 pos.m_get = ScanPos::Get_next_page_dd;
738 case ScanPos::Get_page:
742 if (! (bits & ScanOp::SCAN_DD))
743 pos.m_get = ScanPos::Get_page_mm;
745 pos.m_get = ScanPos::Get_page_dd;
748 case ScanPos::Get_next_page_mm:
753 if (key.m_page_no >= frag.m_max_page_no) {
756 if ((bits & ScanOp::SCAN_NR) && (scan.m_endPage != RNIL))
759 if (key.m_page_no < scan.m_endPage)
762 ndbout_c(
"scanning page %u", key.m_page_no);
767 pos.m_get = ScanPos::Get_undef;
768 scan.m_state = ScanOp::Last;
772 key.m_page_idx = first;
773 pos.m_get = ScanPos::Get_page_mm;
775 pos.m_realpid_mm = RNIL;
778 case ScanPos::Get_page_mm:
782 if (pos.m_realpid_mm == RNIL) {
784 pos.m_realpid_mm = getRealpidCheck(fragPtr.p, key.m_page_no);
786 if (pos.m_realpid_mm == RNIL)
789 if (bits & ScanOp::SCAN_NR)
794 pos.m_get = ScanPos::Get_next_page_mm;
799 c_page_pool.
getPtr(pagePtr, pos.m_realpid_mm);
802 pos.m_page = pagePtr.p;
803 pos.m_get = ScanPos::Get_tuple;
806 case ScanPos::Get_next_page_dd:
813 c_extent_pool.
getPtr(ext_ptr, pos.m_extent_info_ptr_i);
816 if (key.m_page_no >= ext->m_first_page_no + alloc.m_extent_size) {
819 if (! list.
next(ext_ptr)) {
822 pos.m_get = ScanPos::Get_undef;
823 scan.m_state = ScanOp::Last;
828 pos.m_extent_info_ptr_i = ext_ptr.i;
829 ext = c_extent_pool.
getPtr(pos.m_extent_info_ptr_i);
830 key.m_file_no = ext->m_key.m_file_no;
831 key.m_page_no = ext->m_first_page_no;
834 key.m_page_idx = first;
835 pos.m_get = ScanPos::Get_page_dd;
840 if ((bits & ScanOp::SCAN_DD) &&
841 (((key.m_page_no - ext->m_first_page_no) & 7) == 0))
846 preq.m_page = pos.m_key;
847 preq.m_callback = TheNULLCallback;
850 Uint32 read_ahead = m_max_page_read_ahead;
855 Uint32 page_no = preq.m_page.m_page_no;
856 Uint32 page_no_limit = page_no + read_ahead;
857 Uint32
limit = ext->m_first_page_no + alloc.m_extent_size;
858 if (page_no_limit > limit)
862 read_ahead = page_no_limit -
limit;
863 page_no_limit =
limit;
865 if (read_ahead > alloc.m_extent_size)
866 read_ahead = alloc.m_extent_size;
874 while (page_no < page_no_limit)
878 preq.m_page.m_page_no = page_no;
882 pgman.
get_page(signal, preq, flags);
883 m_pgman_ptr = pgman.m_ptr;
887 if (!read_ahead || !list.
next(ext_ptr))
895 preq.m_page.m_file_no = ext->m_key.m_file_no;
896 preq.m_page.m_page_no = ext->m_first_page_no;
901 case ScanPos::Get_page_dd:
906 if (likely(! (bits & ScanOp::SCAN_NR)))
908 D(
"Tablespace_client - scanNext");
912 frag.m_tablespace_id);
913 unsigned uncommitted, committed;
914 uncommitted = committed = ~(unsigned)0;
916 ndbrequire(ret == 0);
917 if (committed == 0 && uncommitted == 0) {
920 pos.m_get = ScanPos::Get_next_page_dd;
926 preq.m_page = pos.m_key;
927 preq.m_callback.m_callbackData = scanPtr.i;
928 preq.m_callback.m_callbackFunction =
929 safe_cast(&Dbtup::disk_page_tup_scan_callback);
932 int res = pgman.
get_page(signal, preq, flags);
933 m_pgman_ptr = pgman.m_ptr;
938 pos.m_get = ScanPos::Get_tuple;
942 pos.m_page = (
Page*)m_pgman_ptr.p;
944 pos.m_get = ScanPos::Get_tuple;
948 case ScanPos::Get_next_tuple:
952 key.m_page_idx +=
size;
953 pos.m_get = ScanPos::Get_tuple;
956 case ScanPos::Get_tuple:
959 if ((bits & ScanOp::SCAN_VS) == 0)
962 if (key.m_page_idx + size <= Fix_page::DATA_WORDS)
964 pos.m_get = ScanPos::Get_next_tuple;
966 if (! (bits & ScanOp::SCAN_DD))
968 Uint32 realpid = getRealpidCheck(fragPtr.p, key.m_page_no);
969 ndbassert(pos.m_realpid_mm == realpid);
974 if (likely(! (bits & ScanOp::SCAN_NR)))
977 thbits = th->m_header_bits;
978 if (! (thbits & Tuple_header::FREE))
985 if (pos.m_realpid_mm == RNIL)
989 goto found_deleted_rowid;
991 thbits = th->m_header_bits;
992 if ((foundGCI = *th->get_mm_gci(tablePtr.p)) > scanGCI ||
995 if (! (thbits & Tuple_header::FREE))
1002 goto found_deleted_rowid;
1005 else if (thbits != Fix_page::FREE_RECORD &&
1016 pos.m_get = ScanPos::Get_next_page;
1023 if (key.m_page_idx < page->high_index)
1026 pos.m_get = ScanPos::Get_next_tuple;
1027 if (!page->is_free(key.m_page_idx))
1030 thbits = th->m_header_bits;
1038 pos.m_get = ScanPos::Get_next_page;
1048 if (! (bits & ScanOp::SCAN_LCP && thbits & Tuple_header::LCP_SKIP)) {
1050 if (! (bits & ScanOp::SCAN_DD)) {
1054 key_mm.assref(th->m_base_record_ref);
1056 pos.m_realpid_mm = getRealpid(fragPtr.p, key_mm.m_page_no);
1059 scan.m_state = ScanOp::Current;
1064 th->m_header_bits = thbits & ~(Uint32)Tuple_header::LCP_SKIP;
1065 if (tablePtr.p->m_bits & Tablerec::TR_Checksum) {
1067 setChecksum(th, tablePtr.p);
1072 found_deleted_rowid:
1075 ndbassert(bits & ScanOp::SCAN_NR);
1077 if (! (bits & ScanOp::SCAN_DD)) {
1082 key_mm.assref(th->m_base_record_ref);
1084 pos.m_realpid_mm = getRealpid(fragPtr.p, key_mm.m_page_no);
1087 th = (
Tuple_header*)(mmpage->m_data + key_mm.m_page_idx);
1088 if ((foundGCI = *th->get_mm_gci(tablePtr.p)) > scanGCI ||
1091 if (! (thbits & Tuple_header::FREE))
1097 conf->scanPtr = scan.m_userPtr;
1098 conf->accOperationPtr = RNIL;
1099 conf->fragId = frag.fragmentId;
1100 conf->localKey[0] = pos.m_key_mm.m_page_no;
1101 conf->localKey[1] = pos.m_key_mm.m_page_idx;
1102 conf->gci = foundGCI;
1103 Uint32 blockNo = refToMain(scan.m_userRef);
1109 scan.m_state = ScanOp::Next;
1117 if (++loop_count >= 32)
1122 signal->theData[0] = ZTUP_SCAN;
1123 signal->theData[1] = scanPtr.i;
1124 sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB);
1129 Dbtup::handle_lcp_keep(
Signal* signal,
1130 Fragrecord* fragPtrP,
1133 TablerecPtr tablePtr;
1134 tablePtr.i = scanPtrP->m_tableId;
1135 ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
1137 ndbassert(!fragPtrP->m_lcp_keep_list_head.isNull());
1138 Local_key tmp = fragPtrP->m_lcp_keep_list_head;
1139 Uint32 * copytuple = get_copy_tuple_raw(&tmp);
1140 memcpy(&fragPtrP->m_lcp_keep_list_head,
1144 if (fragPtrP->m_lcp_keep_list_head.isNull())
1147 ndbassert(tmp.m_page_no == fragPtrP->m_lcp_keep_list_tail.m_page_no);
1148 ndbassert(tmp.m_page_idx == fragPtrP->m_lcp_keep_list_tail.m_page_idx);
1149 fragPtrP->m_lcp_keep_list_tail.setNull();
1153 setCopyTuple(tmp.m_page_no, tmp.m_page_idx);
1155 conf->scanPtr = scanPtrP->m_userPtr;
1156 conf->accOperationPtr = (Uint32)-1;
1157 conf->fragId = fragPtrP->fragmentId;
1158 conf->localKey[0] = tmp.m_page_no;
1159 conf->localKey[1] = tmp.m_page_idx;
1161 Uint32 blockNo = refToMain(scanPtrP->m_userRef);
1168 Dbtup::scanCont(
Signal* signal, ScanOpPtr scanPtr)
1170 bool immediate =
scanNext(signal, scanPtr);
1176 scanReply(signal, scanPtr);
1180 Dbtup::disk_page_tup_scan_callback(
Signal* signal, Uint32 scanPtrI, Uint32 page_i)
1183 c_scanOpPool.
getPtr(scanPtr, scanPtrI);
1184 ScanOp& scan = *scanPtr.p;
1185 ScanPos& pos = scan.m_scanPos;
1188 m_global_page_pool.
getPtr(gptr, page_i);
1189 pos.m_page = (Page*)gptr.p;
1191 scanCont(signal, scanPtr);
1195 Dbtup::scanClose(
Signal* signal, ScanOpPtr scanPtr)
1197 ScanOp& scan = *scanPtr.p;
1198 ndbrequire(! (scan.m_bits & ScanOp::SCAN_LOCK_WAIT) && scan.m_accLockOp == RNIL);
1201 ScanLockPtr lockPtr;
1202 while (list.first(lockPtr)) {
1205 lockReq->returnCode = RNIL;
1206 lockReq->requestInfo = AccLockReq::Abort;
1207 lockReq->accOpPtr = lockPtr.p->m_accLockOp;
1208 EXECUTE_DIRECT(DBACC, GSN_ACC_LOCKREQ, signal, AccLockReq::UndoSignalLength);
1210 ndbrequire(lockReq->returnCode == AccLockReq::Success);
1211 list.release(lockPtr);
1215 conf->scanPtr = scanPtr.p->m_userPtr;
1216 conf->accOperationPtr = RNIL;
1217 conf->fragId = RNIL;
1218 unsigned signalLength = 3;
1219 sendSignal(scanPtr.p->m_userRef, GSN_NEXT_SCANCONF,
1220 signal, signalLength, JBB);
1221 releaseScanOp(scanPtr);
1225 Dbtup::addAccLockOp(ScanOp& scan, Uint32 accLockOp)
1228 ScanLockPtr lockPtr;
1230 list.first(lockPtr);
1231 while (lockPtr.i != RNIL) {
1232 ndbrequire(lockPtr.p->m_accLockOp != accLockOp);
1236 bool ok = list.seize(lockPtr);
1238 lockPtr.p->m_accLockOp = accLockOp;
1242 Dbtup::removeAccLockOp(ScanOp& scan, Uint32 accLockOp)
1245 ScanLockPtr lockPtr;
1246 list.first(lockPtr);
1247 while (lockPtr.i != RNIL) {
1248 if (lockPtr.p->m_accLockOp == accLockOp) {
1254 ndbrequire(lockPtr.i != RNIL);
1255 list.release(lockPtr);
1259 Dbtup::releaseScanOp(ScanOpPtr& scanPtr)
1261 FragrecordPtr fragPtr;
1262 fragPtr.i = scanPtr.p->m_fragPtrI;
1263 ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
1265 if(scanPtr.p->m_bits & ScanOp::SCAN_LCP)
1268 fragPtr.p->m_lcp_scan_op = RNIL;
1269 scanPtr.p->m_fragPtrI = RNIL;
1275 list.release(scanPtr);
1280 Dbtup::execLCP_FRAG_ORD(
Signal* signal)
1285 TablerecPtr tablePtr;
1286 tablePtr.i = req->tableId;
1287 ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
1289 FragrecordPtr fragPtr;
1290 Uint32 fragId = req->fragmentId;
1292 getFragmentrec(fragPtr, fragId, tablePtr.p);
1293 ndbrequire(fragPtr.i != RNIL);
1294 Fragrecord& frag = *fragPtr.p;
1296 ndbrequire(frag.m_lcp_scan_op == RNIL && c_lcp_scan_op != RNIL);
1297 frag.m_lcp_scan_op = c_lcp_scan_op;
1299 c_scanOpPool.
getPtr(scanPtr, frag.m_lcp_scan_op);
1300 ndbrequire(scanPtr.p->m_fragPtrI == RNIL);
1301 new (scanPtr.p) ScanOp;
1302 scanPtr.p->m_fragPtrI = fragPtr.i;
1303 scanPtr.p->m_state = ScanOp::First;
1305 ndbassert(frag.m_lcp_keep_list_head.isNull());
1306 ndbassert(frag.m_lcp_keep_list_tail.isNull());