summaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-11-20 20:38:12 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-11-20 20:38:12 +0000
commit7fc0f06221d22632daa3ff8b70919b43e8a242ca (patch)
treea2ec73a6256c30ba9cb2d4723868978c5136ba5e /src/backend/parser
parent201a45c4fa23c485cf2e14ac9db8064b2c559fdc (diff)
Add a WHEN clause to CREATE TRIGGER, allowing a boolean expression to be
checked to determine whether the trigger should be fired. For BEFORE triggers this is mostly a matter of spec compliance; but for AFTER triggers it can provide a noticeable performance improvement, since queuing of a deferred trigger event and re-fetching of the row(s) at end of statement can be short-circuited if the trigger does not need to be fired. Takahiro Itagaki, reviewed by KaiGai Kohei.
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/gram.y29
1 files changed, 18 insertions, 11 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index e80fffd3bed..cab6d915c8a 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.693 2009/11/16 21:32:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.694 2009/11/20 20:38:10 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -249,6 +249,7 @@ static TypeName *TableFuncTypeName(List *columns);
%type <list> TriggerEvents TriggerOneEvent
%type <value> TriggerFuncArg
+%type <node> TriggerWhen
%type <str> copy_file_name
database_name access_method_clause access_method attr_name
@@ -3227,18 +3228,19 @@ AlterUserMappingStmt: ALTER USER MAPPING FOR auth_ident SERVER name alter_generi
CreateTrigStmt:
CREATE TRIGGER name TriggerActionTime TriggerEvents ON
- qualified_name TriggerForSpec EXECUTE PROCEDURE
- func_name '(' TriggerFuncArgs ')'
+ qualified_name TriggerForSpec TriggerWhen
+ EXECUTE PROCEDURE func_name '(' TriggerFuncArgs ')'
{
CreateTrigStmt *n = makeNode(CreateTrigStmt);
n->trigname = $3;
n->relation = $7;
- n->funcname = $11;
- n->args = $13;
+ n->funcname = $12;
+ n->args = $14;
n->before = $4;
n->row = $8;
n->events = intVal(linitial($5));
n->columns = (List *) lsecond($5);
+ n->whenClause = $9;
n->isconstraint = FALSE;
n->deferrable = FALSE;
n->initdeferred = FALSE;
@@ -3246,20 +3248,20 @@ CreateTrigStmt:
$$ = (Node *)n;
}
| CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
- qualified_name OptConstrFromTable
- ConstraintAttributeSpec
- FOR EACH ROW EXECUTE PROCEDURE
- func_name '(' TriggerFuncArgs ')'
+ qualified_name OptConstrFromTable ConstraintAttributeSpec
+ FOR EACH ROW TriggerWhen
+ EXECUTE PROCEDURE func_name '(' TriggerFuncArgs ')'
{
CreateTrigStmt *n = makeNode(CreateTrigStmt);
n->trigname = $4;
n->relation = $8;
- n->funcname = $16;
- n->args = $18;
+ n->funcname = $17;
+ n->args = $19;
n->before = FALSE;
n->row = TRUE;
n->events = intVal(linitial($6));
n->columns = (List *) lsecond($6);
+ n->whenClause = $14;
n->isconstraint = TRUE;
n->deferrable = ($10 & 1) != 0;
n->initdeferred = ($10 & 2) != 0;
@@ -3335,6 +3337,11 @@ TriggerForType:
| STATEMENT { $$ = FALSE; }
;
+TriggerWhen:
+ WHEN '(' a_expr ')' { $$ = $3; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
TriggerFuncArgs:
TriggerFuncArg { $$ = list_make1($1); }
| TriggerFuncArgs ',' TriggerFuncArg { $$ = lappend($1, $3); }