| 5561 | |
| 5562 | |
| 5563 | static UndoDataRet get_undo_data(thread_db* tdbb, jrd_tra* transaction, |
| 5564 | record_param* rpb, MemoryPool* pool) |
| 5565 | /********************************************************** |
| 5566 | * |
| 5567 | * g e t _ u n d o _ d a t a |
| 5568 | * |
| 5569 | ********************************************************** |
| 5570 | * |
| 5571 | * This is helper routine for the VIO_chase_record_version. It is used to make |
| 5572 | * cursor stable - i.e. cursor should ignore changes made to the record by the |
| 5573 | * inner code. Of course, it is called only when primary record version was |
| 5574 | * created by current transaction: |
| 5575 | * rpb->rpb_transaction_nr == transaction->tra_number. |
| 5576 | * |
| 5577 | * Possible cases and actions: |
| 5578 | * |
| 5579 | * - If record was not changed under current savepoint, return udNone. |
| 5580 | * VIO_chase_record_version should continue own processing. |
| 5581 | * |
| 5582 | * If record was changed under current savepoint, we should read its previous |
| 5583 | * version: |
| 5584 | * |
| 5585 | * - If previous version data is present at undo-log (after update_in_place, |
| 5586 | * for ex.), copy it into rpb and return udExists. |
| 5587 | * VIO_chase_record_version should return true. |
| 5588 | * |
| 5589 | * - If record was inserted or updated and then deleted under current savepoint |
| 5590 | * we should undo two last actions (delete and insert\update), therefore return |
| 5591 | * udForceTwice. |
| 5592 | * VIO_chase_record_version should continue and read second available back |
| 5593 | * version from disk. |
| 5594 | * |
| 5595 | * - Else we need to undo just a last action, so return udForceBack. |
| 5596 | * VIO_chase_record_version should continue and read first available back |
| 5597 | * version from disk. |
| 5598 | * |
| 5599 | * If record version was restored from undo log mark rpb with RPB_s_undo_data |
| 5600 | * to let caller know that data page is already released. |
| 5601 | * |
| 5602 | **********************************************************/ |
| 5603 | { |
| 5604 | if (!transaction->tra_save_point) |
| 5605 | return udNone; |
| 5606 | |
| 5607 | VerbAction* const action = transaction->tra_save_point->getAction(rpb->rpb_relation); |
| 5608 | |
| 5609 | if (action) |
| 5610 | { |
| 5611 | const SINT64 recno = rpb->rpb_number.getValue(); |
| 5612 | if (!RecordBitmap::test(action->vct_records, recno)) |
| 5613 | return udNone; |
| 5614 | |
| 5615 | rpb->rpb_runtime_flags |= RPB_undo_read; |
| 5616 | if (rpb->rpb_flags & rpb_deleted) |
| 5617 | rpb->rpb_runtime_flags |= RPB_undo_deleted; |
| 5618 | |
| 5619 | if (!action->vct_undo || !action->vct_undo->locate(recno)) |
| 5620 | return udForceBack; |
no test coverage detected