Project

General

Profile

Support #2371

trigger behavior

Added by Eric Faulhaber almost 10 years ago. Updated about 8 years ago.

Status:
Closed
Priority:
Normal
Target version:
-
Start date:
Due date:
% Done:

100%

billable:
No
vendor_id:
GCD
case_num:
version:

Related issues

Related to Conversion Tools - Bug #2357: callgraph - set schema triggers as entry points New
Related to Database - Bug #2222: WRITE event triggered too early Hold

History

#1 Updated by Eric Faulhaber almost 10 years ago

Database Trigger Firing Rules

General Sequence

Session triggers generally fire before schema triggers, EXCEPT for the FIND trigger, which is the opposite.

Create Trigger

General

Create trigger fires immediately upon a static (CREATE statement) or dynamic (BUFFER-CREATE method) creation of a record. The trigger fires after the record is created and is in the record buffer.

Errors

I haven't determined how to generate an error condition immediately upon record creation, so I'm not certain whether the trigger would fire in the event of an error condition, but I suspect not. Detection of errors like unique index violations and mandatory field violations is deferred until record validation; they are not detected during processing of the record creation. These types of errors thus do not prevent the firing of the create trigger.

Cyclic prohibitions:
  • Cannot create a record in a buffer while executing that buffer's create trigger (3168).
  • Cannot delete a record in a buffer while executing that buffer's create trigger (3169).

Assign Trigger

General

Assign trigger will fire only when a new value is assigned to the field; reassignment of the current value will not cause the trigger to fire.

Assign trigger fires immediately upon the use of an assignment operator (=).

The use of batch assignments with the ASSIGN keyword causes the assign trigger for each affected field to be deferred until all assignments in the batch have been processed. Upon successful completion of the batch assignment, all assign triggers for fields in the batch fire together, in the order in which they assigned. The target record has all fields specified in the batch assignment updated by the time any of the assign triggers is fired.

BUFFER-COPY

A BUFFER-COPY operation is a specialized form of batch assignment, acting as a batch assignment of all fields. It appears the triggers in this case fire in schema order.

A BUFFER-COPY with the ASSIGN option specified will not fire any field's assign trigger more than once. The "main" buffer copy operation and any fields explicitly specified in an ASSIGN option are handled as a single batch; however, the triggers for any fields copied in the "main" operation are fired first (presumably in schema order). The triggers for any fields specified in the ASSIGN option are fired last, in the order they are assigned.

Errors

In the event of a validation error (single or batch assignment causes immediate record validation), the associated assign trigger(s) will not fire.

Cyclic prohibitions:
  • Cannot create a record in a buffer while executing that buffer's assign trigger (3168).
  • Cannot delete a record in a buffer while executing that buffer's assign trigger (3169).
  • Cannot find a record in a buffer while executing that buffer's assign trigger (2873).

Find Trigger

General

Find trigger is fired when a record is loaded into a buffer from a search operation. Note that reloading a record with FIND CURRENT does not cause the find trigger to fire, even if the lock type is changed. However, finding the same record twice in succession with a search operation does cause the find trigger to fire. It is not fired from a CAN-FIND function, regardless of whether the function reports true.

You can update a found record from within a find trigger, but normal record locking rules apply (i.e., cannot update a record found with NO-LOCK).

Errors

Cyclic prohibitions:
  • Cannot create a record in a buffer while executing that buffer's find trigger (3168).
  • Cannot delete a record in a buffer while executing that buffer's find trigger (3169).
  • Cannot find a record in a buffer while executing that buffer's find trigger (2873).

Write Trigger

General

Write trigger is fired just before an updated record (existing or newly created) is about to undergo standard validation (and is presumably, immediately thereafter written to the database, though the timing of this will differ with P2J).

A prerequisite for the firing of a write trigger is that at least one field in the target record must have been assigned a value different than its current value; reassignment of the current value or default record creation is not enough. Note that this means the release of a newly created record -- if its field values have not been changed -- will NOT cause a write trigger to fire when it is released from the buffer and written to the database, which may be counterintuitive.

The timing of the firing of a write trigger can vary. The following cause this to occur:
  • Explicit release of the record from the buffer, as with the RELEASE statement.
  • Implicit release of the record from the buffer, as when a new record is loaded into the buffer through creation or a query (FIND, FOR, etc.).
  • Explicit validation of the record through the VALIDATE statement.
  • Implicit validation of the record at the earlier of the end of (1) the current, FULL transaction; or (2) the record buffer's scope.

In all cases, it seems to boil down to validation, since even the first two items about record release will cause validation to occur on the exiting record. The write trigger will always fire before standard validation.

[LE: just found an exception to the above rule of write trigger timing: a newly created, invalid record can be found in a different buffer than the one which created it, using a FIND by recid/rowid, without triggering an error. A write trigger which normally would fire at the end of the transaction or buffer scope will NOT fire in this case, before standard validation raises an error, even if a field (would have to be a non-indexed field) previously was updated in that record. Simply removing the FIND statement causes the write trigger to fire normally. This suggests the FIND of the invalid record in a separate buffer somehow (as a side effect?) has marked the record as invalid (but without immediately raising an error at the time of the FIND), and the write trigger is never given a chance to fire.]

Errors

Any errors which cancel out the prerequisite of having at least one field set to a new value will prevent the write trigger from firing. So, even if one or more assignments are successful (and cause associated assign triggers to fire), if a subsequent error causes those good assignments to be undone, the write trigger will not fire.

Cyclic prohibitions:
  • Cannot find a record in a buffer while executing that buffer's write trigger (2873).

Delete Trigger

General

Delete trigger fires immediately upon a static (DELETE statement) or dynamic (BUFFER-DELETE method) deletion of a record. The trigger fires before the record is deleted.

Errors

Cyclic prohibitions:
  • Cannot create a record in a buffer while executing that buffer's delete trigger (3168).
  • Cannot delete a record in a buffer while executing that buffer's delete trigger (3169).
  • Cannot find a record in a buffer while executing that buffer's delete trigger (2873).

Other

I have not done any testing of the replication triggers.

#2 Updated by Eric Faulhaber about 8 years ago

  • Status changed from WIP to Closed
  • % Done changed from 0 to 100

This issue is just meant to be informational. Should be moved to a wiki.

Also available in: Atom PDF