| 49 | } |
| 50 | |
| 51 | void FullTableScan::internalOpen(thread_db* tdbb) const |
| 52 | { |
| 53 | Database* const dbb = tdbb->getDatabase(); |
| 54 | Attachment* const attachment = tdbb->getAttachment(); |
| 55 | Request* const request = tdbb->getRequest(); |
| 56 | Impure* const impure = request->getImpure<Impure>(m_impure); |
| 57 | |
| 58 | impure->irsb_flags = irsb_open; |
| 59 | |
| 60 | RLCK_reserve_relation(tdbb, request->req_transaction, m_relation, false); |
| 61 | |
| 62 | record_param* const rpb = &request->req_rpb[m_stream]; |
| 63 | rpb->getWindow(tdbb).win_flags = 0; |
| 64 | |
| 65 | // Unless this is the only attachment, limit the cache flushing |
| 66 | // effect of large sequential scans on the page working sets of |
| 67 | // other attachments |
| 68 | |
| 69 | if (attachment && (attachment != dbb->dbb_attachments || attachment->att_next)) |
| 70 | { |
| 71 | // If the relation has more data pages than the number of |
| 72 | // pages in the buffer cache then mark the input window |
| 73 | // block as a large scan so that a data page is released |
| 74 | // to the LRU tail after its last record is fetched. |
| 75 | // |
| 76 | // A database backup treats everything as a large scan |
| 77 | // because the cumulative effect of scanning all relations |
| 78 | // is equal to that of a single large relation. |
| 79 | |
| 80 | BufferControl* const bcb = dbb->dbb_bcb; |
| 81 | |
| 82 | if (attachment->isGbak() || DPM_data_pages(tdbb, m_relation) > bcb->bcb_count) |
| 83 | { |
| 84 | rpb->getWindow(tdbb).win_flags = WIN_large_scan; |
| 85 | rpb->rpb_org_scans = m_relation->rel_scan_count++; |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | rpb->rpb_number.setValue(BOF_NUMBER); |
| 90 | |
| 91 | if (m_dbkeyRanges.hasData()) |
| 92 | { |
| 93 | impure->irsb_lower.setValid(false); |
| 94 | impure->irsb_upper.setValid(false); |
| 95 | |
| 96 | EVL_dbkey_bounds(tdbb, m_dbkeyRanges, rpb->rpb_relation, |
| 97 | impure->irsb_lower, impure->irsb_upper); |
| 98 | |
| 99 | if (impure->irsb_lower.isValid()) |
| 100 | { |
| 101 | auto number = impure->irsb_lower.getValue(); |
| 102 | |
| 103 | const auto ppages = rpb->rpb_relation->getPages(tdbb)->rel_pages; |
| 104 | const auto maxRecno = (SINT64) ppages->count() * |
| 105 | dbb->dbb_dp_per_pp * dbb->dbb_max_records - 1; |
| 106 | if (number > maxRecno) |
| 107 | number = maxRecno; |
| 108 |
nothing calls this directly
no test coverage detected