diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f75261160e7..f22e7be5d88 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.287 2009/06/11 20:46:11 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.288 2009/06/18 01:27:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -5206,14 +5206,13 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint, if (on_insert) { fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins"); - fk_trigger->actions[0] = 'i'; + fk_trigger->events = TRIGGER_TYPE_INSERT; } else { fk_trigger->funcname = SystemFuncName("RI_FKey_check_upd"); - fk_trigger->actions[0] = 'u'; + fk_trigger->events = TRIGGER_TYPE_UPDATE; } - fk_trigger->actions[1] = '\0'; fk_trigger->isconstraint = true; fk_trigger->deferrable = fkconstraint->deferrable; @@ -5263,9 +5262,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, fk_trigger->relation = fkconstraint->pktable; fk_trigger->before = false; fk_trigger->row = true; - fk_trigger->actions[0] = 'd'; - fk_trigger->actions[1] = '\0'; - + fk_trigger->events = TRIGGER_TYPE_DELETE; fk_trigger->isconstraint = true; fk_trigger->constrrel = myRel; switch (fkconstraint->fk_del_action) @@ -5316,8 +5313,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, fk_trigger->relation = fkconstraint->pktable; fk_trigger->before = false; fk_trigger->row = true; - fk_trigger->actions[0] = 'u'; - fk_trigger->actions[1] = '\0'; + fk_trigger->events = TRIGGER_TYPE_UPDATE; fk_trigger->isconstraint = true; fk_trigger->constrrel = myRel; switch (fkconstraint->fk_upd_action) diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 08d9593de91..bb628ed80a3 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.247 2009/06/11 14:48:56 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.248 2009/06/18 01:27:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -100,7 +100,6 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid, bool checkPermissions) Oid funcoid; Oid funcrettype; Oid trigoid; - int i; char constrtrigname[NAMEDATALEN]; char *trigname; char *constrname; @@ -150,50 +149,13 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid, bool checkPermissions) TRIGGER_SETT_BEFORE(tgtype); if (stmt->row) TRIGGER_SETT_ROW(tgtype); + tgtype |= stmt->events; - for (i = 0; stmt->actions[i]; i++) - { - switch (stmt->actions[i]) - { - case 'i': - if (TRIGGER_FOR_INSERT(tgtype)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("multiple INSERT events specified"))); - TRIGGER_SETT_INSERT(tgtype); - break; - case 'd': - if (TRIGGER_FOR_DELETE(tgtype)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("multiple DELETE events specified"))); - TRIGGER_SETT_DELETE(tgtype); - break; - case 'u': - if (TRIGGER_FOR_UPDATE(tgtype)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("multiple UPDATE events specified"))); - TRIGGER_SETT_UPDATE(tgtype); - break; - case 't': - if (TRIGGER_FOR_TRUNCATE(tgtype)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("multiple TRUNCATE events specified"))); - TRIGGER_SETT_TRUNCATE(tgtype); - /* Disallow ROW-level TRUNCATE triggers */ - if (stmt->row) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("TRUNCATE FOR EACH ROW triggers are not supported"))); - break; - default: - elog(ERROR, "unrecognized trigger event: %d", - (int) stmt->actions[i]); - break; - } - } + /* Disallow ROW-level TRUNCATE triggers */ + if (TRIGGER_FOR_ROW(tgtype) && TRIGGER_FOR_TRUNCATE(tgtype)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("TRUNCATE FOR EACH ROW triggers are not supported"))); /* * Find and validate the trigger function. diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 4917986e891..72c9877ffd5 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.431 2009/06/11 14:48:58 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.432 2009/06/18 01:27:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -3081,7 +3081,7 @@ _copyCreateTrigStmt(CreateTrigStmt *from) COPY_NODE_FIELD(args); COPY_SCALAR_FIELD(before); COPY_SCALAR_FIELD(row); - strcpy(newnode->actions, from->actions); /* in-line string field */ + COPY_SCALAR_FIELD(events); COPY_SCALAR_FIELD(isconstraint); COPY_SCALAR_FIELD(deferrable); COPY_SCALAR_FIELD(initdeferred); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 78756e6e788..041b96971c6 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -22,7 +22,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.354 2009/06/11 14:48:58 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.355 2009/06/18 01:27:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1639,8 +1639,7 @@ _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b) COMPARE_NODE_FIELD(args); COMPARE_SCALAR_FIELD(before); COMPARE_SCALAR_FIELD(row); - if (strcmp(a->actions, b->actions) != 0) /* in-line string field */ - return false; + COMPARE_SCALAR_FIELD(events); COMPARE_SCALAR_FIELD(isconstraint); COMPARE_SCALAR_FIELD(deferrable); COMPARE_SCALAR_FIELD(initdeferred); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 544b69246ed..280443074f5 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.664 2009/05/27 20:42:29 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.665 2009/06/18 01:27:02 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -53,6 +53,7 @@ #include "catalog/index.h" #include "catalog/namespace.h" +#include "catalog/pg_trigger.h" #include "commands/defrem.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" @@ -244,7 +245,7 @@ static TypeName *TableFuncTypeName(List *columns); %type TriggerActionTime TriggerForSpec opt_trusted opt_restart_seqs %type opt_lancompiler -%type TriggerEvents +%type TriggerEvents TriggerOneEvent %type TriggerFuncArg %type relation_name copy_file_name @@ -266,7 +267,6 @@ static TypeName *TableFuncTypeName(List *columns); %type privilege_target %type function_with_argtypes %type function_with_argtypes_list -%type TriggerOneEvent %type stmtblock stmtmulti OptTableElementList TableElementList OptInherit definition @@ -3133,7 +3133,7 @@ CreateTrigStmt: n->args = $13; n->before = $4; n->row = $8; - memcpy(n->actions, $5, 4); + n->events = $5; n->isconstraint = FALSE; n->deferrable = FALSE; n->initdeferred = FALSE; @@ -3153,11 +3153,10 @@ CreateTrigStmt: n->args = $18; n->before = FALSE; n->row = TRUE; - memcpy(n->actions, $6, 4); + n->events = $6; n->isconstraint = TRUE; n->deferrable = ($10 & 1) != 0; n->initdeferred = ($10 & 2) != 0; - n->constrrel = $9; $$ = (Node *)n; } @@ -3170,30 +3169,20 @@ TriggerActionTime: TriggerEvents: TriggerOneEvent + { $$ = $1; } + | TriggerEvents OR TriggerOneEvent { - char *e = palloc(4); - e[0] = $1; e[1] = '\0'; - $$ = e; - } - | TriggerOneEvent OR TriggerOneEvent - { - char *e = palloc(4); - e[0] = $1; e[1] = $3; e[2] = '\0'; - $$ = e; - } - | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent - { - char *e = palloc(4); - e[0] = $1; e[1] = $3; e[2] = $5; e[3] = '\0'; - $$ = e; + if ($1 & $3) + yyerror("duplicate trigger events specified"); + $$ = $1 | $3; } ; TriggerOneEvent: - INSERT { $$ = 'i'; } - | DELETE_P { $$ = 'd'; } - | UPDATE { $$ = 'u'; } - | TRUNCATE { $$ = 't'; } + INSERT { $$ = TRIGGER_TYPE_INSERT; } + | DELETE_P { $$ = TRIGGER_TYPE_DELETE; } + | UPDATE { $$ = TRIGGER_TYPE_UPDATE; } + | TRUNCATE { $$ = TRIGGER_TYPE_TRUNCATE; } ; TriggerForSpec: diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 54f10078183..7793f66f20f 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -13,7 +13,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.394 2009/06/11 14:49:11 momjian Exp $ + * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.395 2009/06/18 01:27:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1551,7 +1551,8 @@ typedef struct CreateTrigStmt List *args; /* list of (T_String) Values or NIL */ bool before; /* BEFORE/AFTER */ bool row; /* ROW/STATEMENT */ - char actions[4]; /* 1 to 3 of 'i', 'u', 'd', + trailing \0 */ + /* events uses the TRIGGER_TYPE bits defined in catalog/pg_trigger.h */ + int16 events; /* INSERT/UPDATE/DELETE/TRUNCATE */ /* The following are used for referential */ /* integrity constraint triggers */