mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 09:20:39 +01:00
This should fix #6778: Inconsistent cursor-driven deletion
This commit is contained in:
parent
f851cf78a2
commit
585ad1d1c5
@ -2594,9 +2594,6 @@ const StmtNode* EraseNode::erase(thread_db* tdbb, jrd_req* request, WhichTrigger
|
||||
record_param* rpb = &request->req_rpb[stream];
|
||||
jrd_rel* relation = rpb->rpb_relation;
|
||||
|
||||
if (rpb->rpb_number.isBof() || (!relation->rel_view_rse && !rpb->rpb_number.isValid()))
|
||||
ERR_post(Arg::Gds(isc_no_cur_rec));
|
||||
|
||||
switch (request->req_operation)
|
||||
{
|
||||
case jrd_req::req_evaluate:
|
||||
@ -2626,6 +2623,12 @@ const StmtNode* EraseNode::erase(thread_db* tdbb, jrd_req* request, WhichTrigger
|
||||
request->req_operation = jrd_req::req_return;
|
||||
RLCK_reserve_relation(tdbb, transaction, relation, true);
|
||||
|
||||
if (rpb->rpb_runtime_flags & RPB_just_deleted)
|
||||
return parentStmt;
|
||||
|
||||
if (rpb->rpb_number.isBof() || (!relation->rel_view_rse && !rpb->rpb_number.isValid()))
|
||||
ERR_post(Arg::Gds(isc_no_cur_rec));
|
||||
|
||||
if (forNode && forNode->isWriteLockMode(request))
|
||||
{
|
||||
forceWriteLock(tdbb, rpb, transaction);
|
||||
@ -2672,6 +2675,7 @@ const StmtNode* EraseNode::erase(thread_db* tdbb, jrd_req* request, WhichTrigger
|
||||
forNode->setWriteLockMode(request);
|
||||
return parentStmt;
|
||||
}
|
||||
|
||||
REPL_erase(tdbb, rpb, transaction);
|
||||
}
|
||||
|
||||
@ -2698,6 +2702,7 @@ const StmtNode* EraseNode::erase(thread_db* tdbb, jrd_req* request, WhichTrigger
|
||||
}
|
||||
|
||||
rpb->rpb_number.setValid(false);
|
||||
rpb->rpb_runtime_flags |= RPB_just_deleted;
|
||||
|
||||
return parentStmt;
|
||||
}
|
||||
@ -6599,9 +6604,6 @@ const StmtNode* ModifyNode::modify(thread_db* tdbb, jrd_req* request, WhichTrigg
|
||||
record_param* orgRpb = &request->req_rpb[orgStream];
|
||||
jrd_rel* relation = orgRpb->rpb_relation;
|
||||
|
||||
if (orgRpb->rpb_number.isBof() || (!relation->rel_view_rse && !orgRpb->rpb_number.isValid()))
|
||||
ERR_post(Arg::Gds(isc_no_cur_rec));
|
||||
|
||||
record_param* newRpb = &request->req_rpb[newStream];
|
||||
|
||||
switch (request->req_operation)
|
||||
@ -6666,6 +6668,7 @@ const StmtNode* ModifyNode::modify(thread_db* tdbb, jrd_req* request, WhichTrigg
|
||||
forNode->setWriteLockMode(request);
|
||||
return parentStmt;
|
||||
}
|
||||
|
||||
IDX_modify(tdbb, orgRpb, newRpb, transaction);
|
||||
REPL_modify(tdbb, orgRpb, newRpb, transaction);
|
||||
}
|
||||
@ -6718,6 +6721,15 @@ const StmtNode* ModifyNode::modify(thread_db* tdbb, jrd_req* request, WhichTrigg
|
||||
impure->sta_state = 0;
|
||||
RLCK_reserve_relation(tdbb, transaction, relation, true);
|
||||
|
||||
if (orgRpb->rpb_runtime_flags & RPB_just_deleted)
|
||||
{
|
||||
request->req_operation = jrd_req::req_return;
|
||||
return parentStmt;
|
||||
}
|
||||
|
||||
if (orgRpb->rpb_number.isBof() || (!relation->rel_view_rse && !orgRpb->rpb_number.isValid()))
|
||||
ERR_post(Arg::Gds(isc_no_cur_rec));
|
||||
|
||||
if (forNode && (marks & StmtNode::MARK_MERGE))
|
||||
forNode->checkRecordUpdated(tdbb, request, orgRpb);
|
||||
|
||||
|
@ -132,8 +132,10 @@ const USHORT RPB_refetch = 0x01; // re-fetch is required
|
||||
const USHORT RPB_undo_data = 0x02; // data got from undo log
|
||||
const USHORT RPB_undo_read = 0x04; // read was performed using the undo log
|
||||
const USHORT RPB_undo_deleted = 0x08; // read was performed using the undo log, primary version is deleted
|
||||
const USHORT RPB_just_deleted = 0x10; // record was just deleted by us
|
||||
|
||||
const USHORT RPB_UNDO_FLAGS = (RPB_undo_data | RPB_undo_read | RPB_undo_deleted);
|
||||
const USHORT RPB_CLEAR_FLAGS = (RPB_UNDO_FLAGS | RPB_just_deleted);
|
||||
|
||||
const unsigned int MAX_DIFFERENCES = 1024; // Max length of generated Differences string
|
||||
// between two records
|
||||
|
@ -741,7 +741,7 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
|
||||
|
||||
// Take care about modifications performed by our own transaction
|
||||
|
||||
rpb->rpb_runtime_flags &= ~RPB_UNDO_FLAGS;
|
||||
rpb->rpb_runtime_flags &= ~RPB_CLEAR_FLAGS;
|
||||
int forceBack = 0;
|
||||
|
||||
if (rpb->rpb_stream_flags & RPB_s_unstable)
|
||||
|
Loading…
Reference in New Issue
Block a user