Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/dsql/StmtNodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7247,6 +7247,7 @@ const StmtNode* ModifyNode::modify(thread_db* tdbb, Request* request, WhichTrigg
{
const Format* const orgFormat = newFormat;
orgRecord = VIO_record(tdbb, orgRpb, orgFormat, tdbb->getDefaultPool());
orgRecord->setTransactionNumber(orgRpb->rpb_transaction_nr);
orgRpb->rpb_address = orgRecord->getData();
orgRpb->rpb_length = orgFormat->fmt_length;
orgRpb->rpb_format_number = orgFormat->fmt_version;
Expand All @@ -7259,6 +7260,10 @@ const StmtNode* ModifyNode::modify(thread_db* tdbb, Request* request, WhichTrigg
newRpb->rpb_number = orgRpb->rpb_number;
newRpb->rpb_number.setValid(true);

// This allows to use NEW.RDB$RECORD_VERSION in triggers and indices.
// Value for OLD context is already set in VIO_data().
newRpb->rpb_record->setTransactionNumber(transaction->tra_number);

if (mapView)
{
impure->sta_state = 1;
Expand Down Expand Up @@ -8278,6 +8283,9 @@ const StmtNode* StoreNode::store(thread_db* tdbb, Request* request, WhichTrigger
// even if the valid stream marker is present for OLD/NEW trigger contexts
rpb->rpb_number.setValue(BOF_NUMBER);

// This allows to use NEW.RDB$RECORD_VERSION in triggers and indices
rpb->rpb_record->setTransactionNumber(transaction->tra_number);

// CVC: This small block added by Ann Harrison to
// start with a clean empty buffer and so avoid getting
// new record buffer with misleading information. Fixes
Expand Down
17 changes: 14 additions & 3 deletions src/jrd/Savepoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,27 @@ UndoItem::UndoItem(jrd_tra* transaction, RecordNumber recordNumber, const Record
: m_number(recordNumber.getValue()), m_format(record->getFormat())
{
fb_assert(m_format);
m_offset = transaction->getUndoSpace()->allocateSpace(m_format->fmt_length);
transaction->getUndoSpace()->write(m_offset, record->getData(), record->getLength());

// If assert below became wrong at some day, than tx number should be put
// into (and read from) undo space also.
fb_assert(transaction->tra_number == record->getTransactionNumber());

auto undoSpace = transaction->getUndoSpace();

m_offset = undoSpace->allocateSpace(m_format->fmt_length);
undoSpace->write(m_offset, record->getData(), record->getLength());
}

Record* UndoItem::setupRecord(jrd_tra* transaction) const
{
if (m_format)
{
Record* const record = transaction->getUndoRecord(m_format);
transaction->getUndoSpace()->read(m_offset, record->getData(), record->getLength());

auto undoSpace = transaction->getUndoSpace();
undoSpace->read(m_offset, record->getData(), record->getLength());

record->setTransactionNumber(transaction->tra_number);
return record;
}

Expand Down
6 changes: 5 additions & 1 deletion src/jrd/btr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,11 @@ dsc* IndexExpression::evaluate(Record* record) const
const auto orgRequest = m_tdbb->getRequest();
m_tdbb->setRequest(m_request);

m_request->req_rpb[0].rpb_record = record;
auto& rpb = m_request->req_rpb[0];
rpb.rpb_record = record;
// Necessary for evaluation of expressions with RDB$RECORD_VERSION
rpb.rpb_transaction_nr = record->getTransactionNumber();

m_request->req_flags &= ~req_null;

FbLocalStatus status;
Expand Down
6 changes: 6 additions & 0 deletions src/jrd/exe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,9 @@ void EXE_execute_triggers(thread_db* tdbb,
{
trigger->req_rpb[0].rpb_number = old_rpb->rpb_number;
trigger->req_rpb[0].rpb_number.setValid(true);

// This allows to use OLD.RDB$RECORD_VERSION in triggers
trigger->req_rpb[0].rpb_transaction_nr = old_rec->getTransactionNumber();
}
else
trigger->req_rpb[0].rpb_number.setValid(false);
Expand All @@ -1214,6 +1217,9 @@ void EXE_execute_triggers(thread_db* tdbb,
{
trigger->req_rpb[1].rpb_number = new_rpb->rpb_number;
trigger->req_rpb[1].rpb_number.setValid(true);

// This allows to use NEW.RDB$RECORD_VERSION in triggers
trigger->req_rpb[1].rpb_transaction_nr = new_rec->getTransactionNumber();
}
else
trigger->req_rpb[1].rpb_number.setValid(false);
Expand Down
6 changes: 6 additions & 0 deletions src/jrd/replication/Applier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,9 @@ void Applier::doInsert(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)

Savepoint::ChangeMarker marker(transaction->tra_save_point);

// This allows to use RDB$RECORD_VERSION in indices.
rpb->rpb_record->setTransactionNumber(transaction->tra_number);

VIO_store(tdbb, rpb, transaction);
IDX_store(tdbb, rpb, transaction);
if (m_enableCascade)
Expand Down Expand Up @@ -1386,6 +1389,9 @@ void Applier::doUpdate(thread_db* tdbb, record_param* orgRpb, record_param* newR

Savepoint::ChangeMarker marker(transaction->tra_save_point);

// This allows to use NEW.RDB$RECORD_VERSION in indices.
newRpb->rpb_record->setTransactionNumber(transaction->tra_number);

VIO_modify(tdbb, orgRpb, newRpb, transaction);
IDX_modify(tdbb, orgRpb, newRpb, transaction);
if (m_enableCascade)
Expand Down
12 changes: 12 additions & 0 deletions src/jrd/vio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2430,6 +2430,9 @@ bool VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction)
}
}

// Restore transaction number that can be used for OLD.RDB$RECORD_VERSION evaluation later.
rpb->rpb_transaction_nr = tid_fetch;

if (transaction->tra_save_point && transaction->tra_save_point->isChanging())
verb_post(tdbb, transaction, rpb, 0);

Expand Down Expand Up @@ -3711,6 +3714,8 @@ bool VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j

// Old record was restored and re-fetched for write. Now replace it.

const auto orgTranum = org_rpb->rpb_transaction_nr;

org_rpb->rpb_transaction_nr = new_rpb->rpb_transaction_nr;
org_rpb->rpb_format_number = new_rpb->rpb_format_number;
org_rpb->rpb_b_page = temp.rpb_page;
Expand All @@ -3724,6 +3729,9 @@ bool VIO_modify(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb, j

replace_record(tdbb, org_rpb, &stack, transaction);

// Restore transaction number that can be used for OLD.RDB$RECORD_VERSION evaluation later.
org_rpb->rpb_transaction_nr = orgTranum;

if (!(transaction->tra_flags & TRA_system) &&
transaction->tra_save_point && transaction->tra_save_point->isChanging())
{
Expand Down Expand Up @@ -5210,7 +5218,10 @@ static void garbage_collect(thread_db* tdbb, record_param* rpb, ULONG prior_page
delete_record(tdbb, rpb, prior_page, tdbb->getDefaultPool());

if (rpb->rpb_record)
{
rpb->rpb_record->setTransactionNumber(rpb->rpb_transaction_nr);
going.push(rpb->rpb_record);
}

++backversions;

Expand Down Expand Up @@ -5619,6 +5630,7 @@ static UndoDataRet get_undo_data(thread_db* tdbb, jrd_tra* transaction,
record->copyFrom(undoRecord);

rpb->rpb_flags &= ~rpb_deleted;
rpb->rpb_transaction_nr = undoRecord->getTransactionNumber();
return udExists;
}

Expand Down
Loading