MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / undo

Method undo

src/jrd/Savepoint.cpp:248–359  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

246}
247
248void VerbAction::undo(thread_db* tdbb, jrd_tra* transaction, bool preserveLocks, VerbAction* preserveAction)
249{
250 // Undo changes recorded for this verb action.
251 // After that, clear the verb action and prepare it for later reuse.
252
253 record_param rpb;
254 rpb.rpb_relation = vct_relation;
255 rpb.rpb_number.setValue(BOF_NUMBER);
256 rpb.rpb_record = NULL;
257 rpb.getWindow(tdbb).win_flags = 0;
258 rpb.rpb_transaction_nr = transaction->tra_number;
259
260 RecordBitmap::Accessor accessor(vct_records);
261 if (accessor.getFirst())
262 {
263 do
264 {
265 rpb.rpb_number.setValue(accessor.current());
266
267 const bool have_undo = vct_undo && vct_undo->locate(rpb.rpb_number.getValue());
268
269 if (!DPM_get(tdbb, &rpb, LCK_read))
270 BUGCHECK(186); // msg 186 record disappeared
271
272 if ((have_undo || preserveLocks) && !(rpb.rpb_flags & rpb_deleted))
273 VIO_data(tdbb, &rpb, transaction->tra_pool);
274 else
275 CCH_RELEASE(tdbb, &rpb.getWindow(tdbb));
276
277 if (rpb.rpb_transaction_nr != transaction->tra_number)
278 BUGCHECK(185); // msg 185 wrong record version
279
280 if (!have_undo)
281 {
282 if (preserveLocks && rpb.rpb_b_page)
283 {
284 // Fetch previous record version and update in place current version with it
285 record_param temp = rpb;
286 temp.rpb_page = rpb.rpb_b_page;
287 temp.rpb_line = rpb.rpb_b_line;
288 temp.rpb_record = NULL;
289
290 if (temp.rpb_flags & rpb_delta)
291 fb_assert(temp.rpb_prior != NULL);
292 else
293 fb_assert(temp.rpb_prior == NULL);
294
295 if (!DPM_fetch(tdbb, &temp, LCK_read))
296 BUGCHECK(291); // msg 291 cannot find record back version
297
298 if (!(temp.rpb_flags & rpb_chained) || (temp.rpb_flags & (rpb_blob | rpb_fragment)))
299 ERR_bugcheck_msg("invalid back version");
300
301 VIO_data(tdbb, &temp, tdbb->getDefaultPool());
302
303 Record* const save_record = rpb.rpb_record;
304 if (rpb.rpb_flags & rpb_deleted)
305 rpb.rpb_record = NULL;

Callers 1

rollbackMethod · 0.80

Calls 15

VIO_dataFunction · 0.85
CCH_RELEASEFunction · 0.85
ERR_bugcheck_msgFunction · 0.85
VIO_update_in_placeFunction · 0.85
VIO_garbage_collect_idxFunction · 0.85
VIO_backoutFunction · 0.85
setupRecordMethod · 0.80
releaseFunction · 0.50
setValueMethod · 0.45
getFirstMethod · 0.45
currentMethod · 0.45
locateMethod · 0.45

Tested by

no test coverage detected