From 58ae3cf12cbc46211307b6cdcb7304429eca37bd Mon Sep 17 00:00:00 2001 From: Neil Conway Date: Thu, 22 Jan 2004 19:50:21 +0000 Subject: [PATCH] Minor improvements to the trigger documentation, and a few SGML fixes. --- doc/src/sgml/plpgsql.sgml | 16 +++--- doc/src/sgml/trigger.sgml | 102 ++++++++++++++++++++++++-------------- 2 files changed, 74 insertions(+), 44 deletions(-) diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 85fb11a88e5..30f7f3c4802 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -1,5 +1,5 @@ @@ -729,7 +729,7 @@ RENAME oldname TO newname; Using the RENAME declaration you can change the name of a variable, record or row. This is primarily useful if - NEW or OLD should be + NEW or OLD should be referenced by another name inside a trigger procedure. See also ALIAS. @@ -2176,7 +2176,7 @@ RAISE EXCEPTION ''Inexistent ID --> %'', user_id; Data type RECORD; variable holding the new database row for INSERT/UPDATE operations in row-level - triggers. This variable is null in statement-level triggers. + triggers. This variable is NULL in statement-level triggers. @@ -2187,7 +2187,7 @@ RAISE EXCEPTION ''Inexistent ID --> %'', user_id; Data type RECORD; variable holding the old database row for UPDATE/DELETE operations in row-level - triggers. This variable is null in statement-level triggers. + triggers. This variable is NULL in statement-level triggers. @@ -2207,7 +2207,7 @@ RAISE EXCEPTION ''Inexistent ID --> %'', user_id; Data type text; a string of either - BEFORE or AFTER + BEFORE or AFTER depending on the trigger's definition. @@ -2281,9 +2281,9 @@ RAISE EXCEPTION ''Inexistent ID --> %'', user_id; - A trigger function must return either null or a record/row value - having exactly the structure of the table the trigger was fired - for. + A trigger function must return either NULL or a + record/row value having exactly the structure of the table the + trigger was fired for. diff --git a/doc/src/sgml/trigger.sgml b/doc/src/sgml/trigger.sgml index 3c82f48dfb9..79a438da8fb 100644 --- a/doc/src/sgml/trigger.sgml +++ b/doc/src/sgml/trigger.sgml @@ -1,5 +1,5 @@ @@ -45,50 +45,69 @@ $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.33 2003/11/29 19:51:38 pgsql Ex - Trigger functions return a table row (a value of type - HeapTuple) to the calling executor. - A trigger fired before an operation has the following choices: + There are two types of triggers: per-row triggers and + per-statement triggers. In a per-row trigger, the trigger function + is invoked once for every row that is affected by the statement + that fired the trigger. In contrast, a per-statement trigger is + invoked only once when an appropriate statement is executed, + regardless of the number of rows affected by that statement. In + particular, a statement that affects zero rows will still result + in the execution of any applicable per-statement triggers. These + two types of triggers are sometimes called row-level + triggers and statement-level triggers, + respectively. + + + + Trigger functions invoked by per-statement triggers should always + return NULL. Trigger functions invoked by per-row + triggers can return a table row (a value of + type HeapTuple) to the calling executor, + if they choose. A row-level trigger fired before an operation has + the following choices: - It can return a NULL pointer to skip the operation - for the current row (and so the row will not be - inserted/updated/deleted). + It can return NULL to skip the operation for the + current row. This instructs the executor to not perform the + row-level operation that invoked the trigger (the insertion or + modification of a particular table row). - For INSERT and UPDATE - triggers only, the returned row becomes the row that will - be inserted or will replace the row being updated. This - allows the trigger function to modify the row being inserted or - updated. + For row-level INSERT + and UPDATE triggers only, the returned row + becomes the row that will be inserted or will replace the row + being updated. This allows the trigger function to modify the + row being inserted or updated. - A before trigger that does not intend to cause either of these - behaviors must be careful to return as its result the same row that was - passed in (that is, the NEW row for INSERT and - UPDATE triggers, the OLD row for + A row-level before trigger that does not intend to cause either of + these behaviors must be careful to return as its result the same + row that was passed in (that is, the NEW row + for INSERT and UPDATE + triggers, the OLD row for DELETE triggers). - The return - value is ignored for triggers fired after an operation, and so - they may as well return NULL. + The return value is ignored for row-level triggers fired after an + operation, and so they may as well return NULL. If more than one trigger is defined for the same event on the same - relation, the triggers will be fired in alphabetical order by trigger - name. In the case of before triggers, the possibly-modified row - returned by each trigger becomes the input to the next trigger. - If any before trigger returns a NULL pointer, the - operation is abandoned and subsequent triggers are not fired. + relation, the triggers will be fired in alphabetical order by + trigger name. In the case of before triggers, the + possibly-modified row returned by each trigger becomes the input + to the next trigger. If any before trigger returns + NULL, the operation is abandoned and subsequent + triggers are not fired. @@ -134,30 +153,41 @@ $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.33 2003/11/29 19:51:38 pgsql Ex is fired for. Briefly: + - The data change (insertion, update, or deletion) causing the trigger - to fire is naturally - not visible to SQL commands executed in a - before trigger, because it hasn't happened yet. + Statement-level triggers follow simple visibility rules: none of + the changes made by a statement are visible to statement-level + triggers that are invoked before the statement, whereas all + modifications are visible to statement-level after triggers. - However, SQL commands executed in a before trigger - will see the effects of data changes - for rows previously processed in the same outer command. This - requires caution, since the ordering of these change events - is not in general predictable; a SQL command that affects - multiple rows may visit the rows in any order. + The data change (insertion, update, or deletion) causing the + trigger to fire is naturally not visible + to SQL commands executed in a row-level before trigger, because + it hasn't happened yet. - When an after trigger is fired, all data changes made by the outer - command are already complete, and are visible to executed SQL commands. + However, SQL commands executed in a row-level before + trigger will see the effects of data + changes for rows previously processed in the same outer + command. This requires caution, since the ordering of these + change events is not in general predictable; a SQL command that + affects multiple rows may visit the rows in any order. + + + + + + When a row-level after trigger is fired, all data changes made + by the outer command are already complete, and are visible to + the invoked trigger function.