| 6051 | |
| 6052 | |
| 6053 | static PrepareResult prepare_update(thread_db* tdbb, jrd_tra* transaction, TraNumber commit_tid_read, |
| 6054 | record_param* rpb, record_param* temp, record_param* new_rpb, PageStack& stack, bool writelock) |
| 6055 | { |
| 6056 | /************************************** |
| 6057 | * |
| 6058 | * p r e p a r e _ u p d a t e |
| 6059 | * |
| 6060 | ************************************** |
| 6061 | * |
| 6062 | * Functional description |
| 6063 | * Prepare for a modify or erase. Store the old version |
| 6064 | * of a record, fetch the current version, check transaction |
| 6065 | * states, etc. |
| 6066 | * |
| 6067 | **************************************/ |
| 6068 | SET_TDBB(tdbb); |
| 6069 | |
| 6070 | jrd_rel* const relation = rpb->rpb_relation; |
| 6071 | |
| 6072 | #ifdef VIO_DEBUG |
| 6073 | VIO_trace(DEBUG_TRACE_ALL, |
| 6074 | "prepare_update (rel_id %u, transaction %" SQUADFORMAT |
| 6075 | ", commit_tid read %" SQUADFORMAT", record_param %" QUADFORMAT"d, ", |
| 6076 | relation->rel_id, transaction ? transaction->tra_number : 0, commit_tid_read, |
| 6077 | rpb ? rpb->rpb_number.getValue() : 0); |
| 6078 | |
| 6079 | VIO_trace(DEBUG_TRACE_ALL, |
| 6080 | " temp_rpb %" QUADFORMAT"d, new_rpb %" QUADFORMAT"d, stack)\n", |
| 6081 | temp ? temp->rpb_number.getValue() : 0, |
| 6082 | new_rpb ? new_rpb->rpb_number.getValue() : 0); |
| 6083 | |
| 6084 | VIO_trace(DEBUG_TRACE_ALL_INFO, |
| 6085 | " old record %" SLONGFORMAT":%d, rpb_trans %" SQUADFORMAT |
| 6086 | ", flags %d, back %" SLONGFORMAT":%d, fragment %" SLONGFORMAT |
| 6087 | ":%d, prior %p\n", |
| 6088 | rpb->rpb_page, rpb->rpb_line, rpb->rpb_transaction_nr, |
| 6089 | rpb->rpb_flags, rpb->rpb_b_page, rpb->rpb_b_line, |
| 6090 | rpb->rpb_f_page, rpb->rpb_f_line, (void*) rpb->rpb_prior); |
| 6091 | #endif |
| 6092 | |
| 6093 | /* We're almost ready to go. To erase the record, we must first |
| 6094 | make a copy of the old record someplace else. Then we must re-fetch |
| 6095 | the record (for write) and verify that it is legal for us to |
| 6096 | erase it -- that it was written by a transaction that was committed |
| 6097 | when we started. If not, the transaction that wrote the record |
| 6098 | is either active, dead, or in limbo. If the transaction is active, |
| 6099 | wait for it to finish. If it commits, we can't procede and must |
| 6100 | return an update conflict. If the transaction is dead, back out the |
| 6101 | old version of the record and try again. If in limbo, punt. |
| 6102 | |
| 6103 | The above is true only for concurrency & consistency mode transactions. |
| 6104 | For read committed transactions, check if the latest commited version |
| 6105 | is the same as the version that was read for the update. If yes, |
| 6106 | the update can take place. If some other transaction has modified |
| 6107 | the record and committed, then an update error will be returned. |
| 6108 | */ |
| 6109 | |
| 6110 | *temp = *rpb; |
no test coverage detected