Execute a MODIFY statement.
| 7062 | |
| 7063 | // Execute a MODIFY statement. |
| 7064 | const StmtNode* ModifyNode::modify(thread_db* tdbb, Request* request, WhichTrigger whichTrig) const |
| 7065 | { |
| 7066 | jrd_tra* transaction = request->req_transaction; |
| 7067 | impure_state* impure = request->getImpure<impure_state>(impureOffset); |
| 7068 | |
| 7069 | record_param* orgRpb = &request->req_rpb[orgStream]; |
| 7070 | jrd_rel* relation = orgRpb->rpb_relation; |
| 7071 | |
| 7072 | record_param* newRpb = &request->req_rpb[newStream]; |
| 7073 | |
| 7074 | switch (request->req_operation) |
| 7075 | { |
| 7076 | case Request::req_evaluate: |
| 7077 | if (!(marks & MARK_AVOID_COUNTERS)) |
| 7078 | request->req_records_affected.bumpModified(false); |
| 7079 | |
| 7080 | if (impure->sta_state == 0 && forNode && forNode->isWriteLockMode(request)) |
| 7081 | request->req_operation = Request::req_return; |
| 7082 | // fall thru |
| 7083 | else |
| 7084 | break; |
| 7085 | |
| 7086 | case Request::req_return: |
| 7087 | if (impure->sta_state == 1) |
| 7088 | { |
| 7089 | impure->sta_state = 0; |
| 7090 | Record* orgRecord = orgRpb->rpb_record; |
| 7091 | const Record* newRecord = newRpb->rpb_record; |
| 7092 | orgRecord->copyDataFrom(newRecord, true); |
| 7093 | request->req_operation = Request::req_evaluate; |
| 7094 | return statement; |
| 7095 | } |
| 7096 | |
| 7097 | if (impure->sta_state == 0) |
| 7098 | { |
| 7099 | if (forNode && forNode->isWriteLockMode(request)) |
| 7100 | { |
| 7101 | forceWriteLock(tdbb, orgRpb, transaction); |
| 7102 | return parentStmt; |
| 7103 | } |
| 7104 | |
| 7105 | // CVC: This call made here to clear the record in each NULL field and |
| 7106 | // varchar field whose tail may contain garbage. |
| 7107 | cleanupRpb(tdbb, newRpb); |
| 7108 | |
| 7109 | SavepointChangeMarker scMarker(transaction); |
| 7110 | |
| 7111 | // Prepare to undo changes by PRE-triggers if record is locked by another |
| 7112 | // transaction and update should be skipped. |
| 7113 | const bool skipLocked = orgRpb->rpb_stream_flags & RPB_s_skipLocked; |
| 7114 | CondSavepointAndMarker spPreTriggers(tdbb, transaction, |
| 7115 | skipLocked && !(transaction->tra_flags & TRA_system) && relation->rel_pre_modify); |
| 7116 | |
| 7117 | preModifyEraseTriggers(tdbb, &relation->rel_pre_modify, whichTrig, orgRpb, newRpb, |
| 7118 | TRIGGER_UPDATE); |
| 7119 | |
| 7120 | if (validations.hasData()) |
| 7121 | validateExpressions(tdbb, validations); |
nothing calls this directly
no test coverage detected