| 479 | } |
| 480 | |
| 481 | Savepoint* Savepoint::rollforward(thread_db* tdbb, Savepoint* prior) |
| 482 | { |
| 483 | // Merge changes made in this savepoint into next one. |
| 484 | // Perform index and BLOB cleanup if needed. |
| 485 | // At the exit savepoint is clear and safe to reuse. |
| 486 | |
| 487 | jrd_tra* const old_tran = tdbb->getTransaction(); |
| 488 | |
| 489 | try |
| 490 | { |
| 491 | // If the current to-be-cleaned-up savepoint is very big, and the next |
| 492 | // level savepoint is the transaction level savepoint, then get rid of |
| 493 | // the transaction level savepoint now (instead of after making the |
| 494 | // transaction level savepoint very very big). |
| 495 | |
| 496 | if (m_next && m_next->isRoot() && this->isLarge()) |
| 497 | { |
| 498 | fb_assert(!m_next->m_next); // check that transaction savepoint is the last in list |
| 499 | // get rid of tx-level savepoint |
| 500 | m_next->rollforward(tdbb); |
| 501 | m_next = NULL; |
| 502 | } |
| 503 | |
| 504 | // Cleanup/merge deferred work/event post |
| 505 | |
| 506 | if (m_actions || (m_flags & SAV_force_dfw)) |
| 507 | { |
| 508 | DFW_merge_work(m_transaction, m_number, m_next ? m_next->m_number : 0); |
| 509 | |
| 510 | if (m_next && (m_flags & SAV_force_dfw)) |
| 511 | m_next->m_flags |= SAV_force_dfw; |
| 512 | |
| 513 | m_flags &= ~SAV_force_dfw; |
| 514 | } |
| 515 | |
| 516 | tdbb->tdbb_flags |= TDBB_verb_cleanup; |
| 517 | tdbb->setTransaction(m_transaction); |
| 518 | |
| 519 | while (m_actions) |
| 520 | { |
| 521 | VerbAction* const action = m_actions; |
| 522 | VerbAction* nextAction = NULL; |
| 523 | |
| 524 | if (m_next) |
| 525 | { |
| 526 | nextAction = m_next->getAction(action->vct_relation); |
| 527 | |
| 528 | if (!nextAction) // next savepoint didn't touch this table yet - send whole action |
| 529 | { |
| 530 | m_actions = action->vct_next; |
| 531 | action->vct_next = m_next->m_actions; |
| 532 | m_next->m_actions = action; |
| 533 | continue; |
| 534 | } |
| 535 | } |
| 536 | |
| 537 | // No luck, merge action in a slow way |
| 538 | action->mergeTo(tdbb, m_transaction, nextAction); |
no test coverage detected