From 58ae3cf12cbc46211307b6cdcb7304429eca37bd Mon Sep 17 00:00:00 2001 From: Neil Conway <neilc@samurai.com> 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 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.32 2003/11/30 05:45:22 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.33 2004/01/22 19:50:21 neilc Exp $ --> <chapter id="plpgsql"> @@ -729,7 +729,7 @@ RENAME <replaceable>oldname</replaceable> TO <replaceable>newname</replaceable>; <para> Using the <literal>RENAME</literal> declaration you can change the name of a variable, record or row. This is primarily useful if - <literal>NEW</literal> or <literal>OLD</literal> should be + <varname>NEW</varname> or <varname>OLD</varname> should be referenced by another name inside a trigger procedure. See also <literal>ALIAS</literal>. </para> @@ -2176,7 +2176,7 @@ RAISE EXCEPTION ''Inexistent ID --> %'', user_id; <para> Data type <type>RECORD</type>; variable holding the new database row for <command>INSERT</>/<command>UPDATE</> operations in row-level - triggers. This variable is null in statement-level triggers. + triggers. This variable is <symbol>NULL</symbol> in statement-level triggers. </para> </listitem> </varlistentry> @@ -2187,7 +2187,7 @@ RAISE EXCEPTION ''Inexistent ID --> %'', user_id; <para> Data type <type>RECORD</type>; variable holding the old database row for <command>UPDATE</>/<command>DELETE</> operations in row-level - triggers. This variable is null in statement-level triggers. + triggers. This variable is <symbol>NULL</symbol> in statement-level triggers. </para> </listitem> </varlistentry> @@ -2207,7 +2207,7 @@ RAISE EXCEPTION ''Inexistent ID --> %'', user_id; <listitem> <para> Data type <type>text</type>; a string of either - <literal>BEFORE</literal> or <literal>AFTER</literal> + <literal>BEFORE</literal> or <literal>AFTER</literal> depending on the trigger's definition. </para> </listitem> @@ -2281,9 +2281,9 @@ RAISE EXCEPTION ''Inexistent ID --> %'', user_id; </para> <para> - 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 <symbol>NULL</symbol> or a + record/row value having exactly the structure of the table the + trigger was fired for. </para> <para> 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 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.33 2003/11/29 19:51:38 pgsql Exp $ +$PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.34 2004/01/22 19:50:21 neilc Exp $ --> <chapter id="triggers"> @@ -45,50 +45,69 @@ $PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.33 2003/11/29 19:51:38 pgsql Ex </para> <para> - Trigger functions return a table row (a value of type - <structname>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 <quote>row-level + triggers</quote> and <quote>statement-level triggers</quote>, + respectively. + </para> + + <para> + Trigger functions invoked by per-statement triggers should always + return <symbol>NULL</symbol>. Trigger functions invoked by per-row + triggers can return a table row (a value of + type <structname>HeapTuple</structname>) to the calling executor, + if they choose. A row-level trigger fired before an operation has + the following choices: <itemizedlist> <listitem> <para> - It can return a <symbol>NULL</> pointer to skip the operation - for the current row (and so the row will not be - inserted/updated/deleted). + It can return <symbol>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). </para> </listitem> <listitem> <para> - For <command>INSERT</command> and <command>UPDATE</command> - 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 <command>INSERT</command> + and <command>UPDATE</command> 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. </para> </listitem> </itemizedlist> - 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 <command>INSERT</command> and - <command>UPDATE</command> 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 <varname>NEW</varname> row + for <command>INSERT</command> and <command>UPDATE</command> + triggers, the <varname>OLD</varname> row for <command>DELETE</command> triggers). </para> <para> - The return - value is ignored for triggers fired after an operation, and so - they may as well return <symbol>NULL</>. + The return value is ignored for row-level triggers fired after an + operation, and so they may as well return <symbol>NULL</>. </para> <para> 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 <symbol>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 + <symbol>NULL</>, the operation is abandoned and subsequent + triggers are not fired. </para> <para> @@ -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: <itemizedlist> + + <listitem> + <para> + 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. + </para> + </listitem> + <listitem> <para> - The data change (insertion, update, or deletion) causing the trigger - to fire is naturally - <emphasis>not</emphasis> visible to SQL commands executed in a - before trigger, because it hasn't happened yet. + The data change (insertion, update, or deletion) causing the + trigger to fire is naturally <emphasis>not</emphasis> visible + to SQL commands executed in a row-level before trigger, because + it hasn't happened yet. </para> </listitem> <listitem> <para> - However, SQL commands executed in a before trigger - <emphasis>will</emphasis> 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. + However, SQL commands executed in a row-level before + trigger <emphasis>will</emphasis> 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. </para> </listitem> <listitem> <para> - When an after trigger is fired, all data changes made by the outer - command are already complete, and are visible to executed SQL commands. + 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. </para> </listitem> </itemizedlist> -- GitLab