diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2009-11-20 20:38:12 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2009-11-20 20:38:12 +0000 |
commit | 7fc0f06221d22632daa3ff8b70919b43e8a242ca (patch) | |
tree | a2ec73a6256c30ba9cb2d4723868978c5136ba5e /src/backend/parser | |
parent | 201a45c4fa23c485cf2e14ac9db8064b2c559fdc (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.y | 29 |
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); } |