| 3769 | |
| 3770 | |
| 3771 | bool VIO_next_record(thread_db* tdbb, |
| 3772 | record_param* rpb, |
| 3773 | jrd_tra* transaction, |
| 3774 | MemoryPool* pool, |
| 3775 | FindNextRecordScope scope, |
| 3776 | const RecordNumber* upper) |
| 3777 | { |
| 3778 | /************************************** |
| 3779 | * |
| 3780 | * V I O _ n e x t _ r e c o r d |
| 3781 | * |
| 3782 | ************************************** |
| 3783 | * |
| 3784 | * Functional description |
| 3785 | * Get the next record in a record stream. |
| 3786 | * |
| 3787 | **************************************/ |
| 3788 | SET_TDBB(tdbb); |
| 3789 | |
| 3790 | // Fetch data page from a modify/erase input stream with a write |
| 3791 | // lock. This saves an upward conversion to a write lock when |
| 3792 | // refetching the page in the context of the output stream. |
| 3793 | |
| 3794 | const USHORT lock_type = (rpb->rpb_stream_flags & RPB_s_update) ? LCK_write : LCK_read; |
| 3795 | |
| 3796 | #ifdef VIO_DEBUG |
| 3797 | jrd_rel* relation = rpb->rpb_relation; |
| 3798 | VIO_trace(DEBUG_TRACE, |
| 3799 | "VIO_next_record (rel_id %u, record_param %" QUADFORMAT"d, transaction %" SQUADFORMAT", pool %p)\n", |
| 3800 | relation->rel_id, rpb->rpb_number.getValue(), transaction ? transaction->tra_number : 0, |
| 3801 | (void*) pool); |
| 3802 | |
| 3803 | VIO_trace(DEBUG_TRACE_INFO, |
| 3804 | " record %" SLONGFORMAT":%d, rpb_trans %" SQUADFORMAT |
| 3805 | ", flags %d, back %" SLONGFORMAT":%d, fragment %" SLONGFORMAT":%d\n", |
| 3806 | rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, |
| 3807 | rpb->rpb_flags, rpb->rpb_b_page, rpb->rpb_b_line, |
| 3808 | rpb->rpb_f_page, rpb->rpb_f_line); |
| 3809 | #endif |
| 3810 | |
| 3811 | do |
| 3812 | { |
| 3813 | if (!DPM_next(tdbb, rpb, lock_type, scope)) |
| 3814 | return false; |
| 3815 | |
| 3816 | if (upper && rpb->rpb_number > *upper) |
| 3817 | { |
| 3818 | CCH_RELEASE(tdbb, &rpb->getWindow(tdbb)); |
| 3819 | return false; |
| 3820 | } |
| 3821 | } while (!VIO_chase_record_version(tdbb, rpb, transaction, pool, false, false)); |
| 3822 | |
| 3823 | if (rpb->rpb_runtime_flags & RPB_undo_data) |
| 3824 | fb_assert(rpb->getWindow(tdbb).win_bdb == NULL); |
| 3825 | else |
| 3826 | fb_assert(rpb->getWindow(tdbb).win_bdb != NULL); |
| 3827 | |
| 3828 | if (pool && !(rpb->rpb_runtime_flags & RPB_undo_data)) |
no test coverage detected