| 2487 | } |
| 2488 | |
| 2489 | static void delete_version_chain(thread_db* tdbb, record_param* rpb, bool delete_head) |
| 2490 | { |
| 2491 | /************************************** |
| 2492 | * |
| 2493 | * d e l e t e _ v e r s i o n _ c h a i n |
| 2494 | * |
| 2495 | ************************************** |
| 2496 | * |
| 2497 | * Functional description |
| 2498 | * Delete a chain of back record versions. This is called from |
| 2499 | * VIO_intermediate_gc. One enters this routine with an |
| 2500 | * inactive record_param for a version chain that has |
| 2501 | * 1) just been created and never attached to primary version or |
| 2502 | * (delete_head = true) |
| 2503 | * 2) just had been replaced with another version chain |
| 2504 | * (delete_head = false) |
| 2505 | * Therefore we can do a fetch on the back pointers we've got |
| 2506 | * because we have the last existing copy of them. |
| 2507 | * |
| 2508 | **************************************/ |
| 2509 | #ifdef VIO_DEBUG |
| 2510 | VIO_trace(DEBUG_TRACE, |
| 2511 | "delete_version_chain (record_param %" SQUADFORMAT", delete_head %s)\n", |
| 2512 | rpb->rpb_number.getValue(), delete_head ? "true" : "false"); |
| 2513 | |
| 2514 | VIO_trace(DEBUG_TRACE_INFO, |
| 2515 | " record %" SLONGFORMAT":%d, rpb_trans %" SQUADFORMAT |
| 2516 | ", flags %d, back %" SLONGFORMAT":%d, fragment %" SLONGFORMAT":%d\n", |
| 2517 | rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, |
| 2518 | rpb->rpb_flags, rpb->rpb_b_page, rpb->rpb_b_line, |
| 2519 | rpb->rpb_f_page, rpb->rpb_f_line); |
| 2520 | #endif |
| 2521 | |
| 2522 | // It's possible to get rpb_page == 0 from VIO_intermediate_gc via |
| 2523 | // staying_chain_rpb. This case happens there when the staying record |
| 2524 | // stack has 1 item at the moment this rpb is created. So return to |
| 2525 | // avoid an error on DPM_fetch below. |
| 2526 | if (!rpb->rpb_page) |
| 2527 | return; |
| 2528 | |
| 2529 | ULONG prior_page = 0; |
| 2530 | |
| 2531 | // Note that the page number of the oldest version in the chain should |
| 2532 | // be stored in rpb->rpb_page before exiting this function because |
| 2533 | // VIO_intermediate_gc will use it as a prior page number. |
| 2534 | while (rpb->rpb_b_page != 0 || delete_head) |
| 2535 | { |
| 2536 | if (!delete_head) |
| 2537 | { |
| 2538 | prior_page = rpb->rpb_page; |
| 2539 | rpb->rpb_page = rpb->rpb_b_page; |
| 2540 | rpb->rpb_line = rpb->rpb_b_line; |
| 2541 | } |
| 2542 | else |
| 2543 | delete_head = false; |
| 2544 | |
| 2545 | if (!DPM_fetch(tdbb, rpb, LCK_write)) |
| 2546 | BUGCHECK(291); // msg 291 cannot find record back version |
no test coverage detected