| 2921 | |
| 2922 | |
| 2923 | bool VIO_get(thread_db* tdbb, record_param* rpb, jrd_tra* transaction, MemoryPool* pool) |
| 2924 | { |
| 2925 | /************************************** |
| 2926 | * |
| 2927 | * V I O _ g e t |
| 2928 | * |
| 2929 | ************************************** |
| 2930 | * |
| 2931 | * Functional description |
| 2932 | * Get a specific record from a relation. |
| 2933 | * |
| 2934 | **************************************/ |
| 2935 | SET_TDBB(tdbb); |
| 2936 | |
| 2937 | #ifdef VIO_DEBUG |
| 2938 | jrd_rel* relation = rpb->rpb_relation; |
| 2939 | VIO_trace(DEBUG_READS, |
| 2940 | "VIO_get (rel_id %u, record_param %" QUADFORMAT"d, transaction %" SQUADFORMAT", pool %p)\n", |
| 2941 | relation->rel_id, rpb->rpb_number.getValue(), transaction ? transaction->tra_number : 0, |
| 2942 | (void*) pool); |
| 2943 | #endif |
| 2944 | |
| 2945 | // Fetch data page from a modify/erase input stream with a write |
| 2946 | // lock. This saves an upward conversion to a write lock when |
| 2947 | // refetching the page in the context of the output stream. |
| 2948 | |
| 2949 | const USHORT lock_type = (rpb->rpb_stream_flags & RPB_s_update) ? LCK_write : LCK_read; |
| 2950 | |
| 2951 | if (!DPM_get(tdbb, rpb, lock_type) || |
| 2952 | !VIO_chase_record_version(tdbb, rpb, transaction, pool, false, false)) |
| 2953 | { |
| 2954 | return false; |
| 2955 | } |
| 2956 | |
| 2957 | #ifdef VIO_DEBUG |
| 2958 | VIO_trace(DEBUG_READS_INFO, |
| 2959 | " record %" SLONGFORMAT":%d, rpb_trans %" SQUADFORMAT |
| 2960 | ", flags %d, back %" SLONGFORMAT":%d, fragment %" SLONGFORMAT":%d\n", |
| 2961 | rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, |
| 2962 | rpb->rpb_flags, rpb->rpb_b_page, rpb->rpb_b_line, |
| 2963 | rpb->rpb_f_page, rpb->rpb_f_line); |
| 2964 | #endif |
| 2965 | |
| 2966 | if (rpb->rpb_runtime_flags & RPB_undo_data) |
| 2967 | fb_assert(rpb->getWindow(tdbb).win_bdb == NULL); |
| 2968 | else |
| 2969 | fb_assert(rpb->getWindow(tdbb).win_bdb != NULL); |
| 2970 | |
| 2971 | if (pool && !(rpb->rpb_runtime_flags & RPB_undo_data)) |
| 2972 | { |
| 2973 | if (rpb->rpb_stream_flags & RPB_s_no_data) |
| 2974 | { |
| 2975 | CCH_RELEASE(tdbb, &rpb->getWindow(tdbb)); |
| 2976 | rpb->rpb_address = NULL; |
| 2977 | rpb->rpb_length = 0; |
| 2978 | } |
| 2979 | else |
| 2980 | VIO_data(tdbb, rpb, pool); |
no test coverage detected