Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f08e5e9

Browse files
committed
Fix the just-reported problem that you can't specify all four trigger event
types in CREATE TRIGGER. While at it, clean up the amazingly tedious and inextensible way that the trigger event type list was handled. Per report from Greg Sabino Mullane.
1 parent c30446b commit f08e5e9

File tree

6 files changed

+33
-86
lines changed

6 files changed

+33
-86
lines changed

src/backend/commands/tablecmds.c

+5-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.287 2009/06/11 20:46:11 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.288 2009/06/18 01:27:02 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -5206,14 +5206,13 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint,
52065206
if (on_insert)
52075207
{
52085208
fk_trigger->funcname = SystemFuncName("RI_FKey_check_ins");
5209-
fk_trigger->actions[0] = 'i';
5209+
fk_trigger->events = TRIGGER_TYPE_INSERT;
52105210
}
52115211
else
52125212
{
52135213
fk_trigger->funcname = SystemFuncName("RI_FKey_check_upd");
5214-
fk_trigger->actions[0] = 'u';
5214+
fk_trigger->events = TRIGGER_TYPE_UPDATE;
52155215
}
5216-
fk_trigger->actions[1] = '\0';
52175216

52185217
fk_trigger->isconstraint = true;
52195218
fk_trigger->deferrable = fkconstraint->deferrable;
@@ -5263,9 +5262,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
52635262
fk_trigger->relation = fkconstraint->pktable;
52645263
fk_trigger->before = false;
52655264
fk_trigger->row = true;
5266-
fk_trigger->actions[0] = 'd';
5267-
fk_trigger->actions[1] = '\0';
5268-
5265+
fk_trigger->events = TRIGGER_TYPE_DELETE;
52695266
fk_trigger->isconstraint = true;
52705267
fk_trigger->constrrel = myRel;
52715268
switch (fkconstraint->fk_del_action)
@@ -5316,8 +5313,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
53165313
fk_trigger->relation = fkconstraint->pktable;
53175314
fk_trigger->before = false;
53185315
fk_trigger->row = true;
5319-
fk_trigger->actions[0] = 'u';
5320-
fk_trigger->actions[1] = '\0';
5316+
fk_trigger->events = TRIGGER_TYPE_UPDATE;
53215317
fk_trigger->isconstraint = true;
53225318
fk_trigger->constrrel = myRel;
53235319
switch (fkconstraint->fk_upd_action)

src/backend/commands/trigger.c

+7-45
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.247 2009/06/11 14:48:56 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.248 2009/06/18 01:27:02 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -100,7 +100,6 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid, bool checkPermissions)
100100
Oid funcoid;
101101
Oid funcrettype;
102102
Oid trigoid;
103-
int i;
104103
char constrtrigname[NAMEDATALEN];
105104
char *trigname;
106105
char *constrname;
@@ -150,50 +149,13 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid, bool checkPermissions)
150149
TRIGGER_SETT_BEFORE(tgtype);
151150
if (stmt->row)
152151
TRIGGER_SETT_ROW(tgtype);
152+
tgtype |= stmt->events;
153153

154-
for (i = 0; stmt->actions[i]; i++)
155-
{
156-
switch (stmt->actions[i])
157-
{
158-
case 'i':
159-
if (TRIGGER_FOR_INSERT(tgtype))
160-
ereport(ERROR,
161-
(errcode(ERRCODE_SYNTAX_ERROR),
162-
errmsg("multiple INSERT events specified")));
163-
TRIGGER_SETT_INSERT(tgtype);
164-
break;
165-
case 'd':
166-
if (TRIGGER_FOR_DELETE(tgtype))
167-
ereport(ERROR,
168-
(errcode(ERRCODE_SYNTAX_ERROR),
169-
errmsg("multiple DELETE events specified")));
170-
TRIGGER_SETT_DELETE(tgtype);
171-
break;
172-
case 'u':
173-
if (TRIGGER_FOR_UPDATE(tgtype))
174-
ereport(ERROR,
175-
(errcode(ERRCODE_SYNTAX_ERROR),
176-
errmsg("multiple UPDATE events specified")));
177-
TRIGGER_SETT_UPDATE(tgtype);
178-
break;
179-
case 't':
180-
if (TRIGGER_FOR_TRUNCATE(tgtype))
181-
ereport(ERROR,
182-
(errcode(ERRCODE_SYNTAX_ERROR),
183-
errmsg("multiple TRUNCATE events specified")));
184-
TRIGGER_SETT_TRUNCATE(tgtype);
185-
/* Disallow ROW-level TRUNCATE triggers */
186-
if (stmt->row)
187-
ereport(ERROR,
188-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
189-
errmsg("TRUNCATE FOR EACH ROW triggers are not supported")));
190-
break;
191-
default:
192-
elog(ERROR, "unrecognized trigger event: %d",
193-
(int) stmt->actions[i]);
194-
break;
195-
}
196-
}
154+
/* Disallow ROW-level TRUNCATE triggers */
155+
if (TRIGGER_FOR_ROW(tgtype) && TRIGGER_FOR_TRUNCATE(tgtype))
156+
ereport(ERROR,
157+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
158+
errmsg("TRUNCATE FOR EACH ROW triggers are not supported")));
197159

198160
/*
199161
* Find and validate the trigger function.

src/backend/nodes/copyfuncs.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.431 2009/06/11 14:48:58 momjian Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.432 2009/06/18 01:27:02 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -3081,7 +3081,7 @@ _copyCreateTrigStmt(CreateTrigStmt *from)
30813081
COPY_NODE_FIELD(args);
30823082
COPY_SCALAR_FIELD(before);
30833083
COPY_SCALAR_FIELD(row);
3084-
strcpy(newnode->actions, from->actions); /* in-line string field */
3084+
COPY_SCALAR_FIELD(events);
30853085
COPY_SCALAR_FIELD(isconstraint);
30863086
COPY_SCALAR_FIELD(deferrable);
30873087
COPY_SCALAR_FIELD(initdeferred);

src/backend/nodes/equalfuncs.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* Portions Copyright (c) 1994, Regents of the University of California
2323
*
2424
* IDENTIFICATION
25-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.354 2009/06/11 14:48:58 momjian Exp $
25+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.355 2009/06/18 01:27:02 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -1639,8 +1639,7 @@ _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
16391639
COMPARE_NODE_FIELD(args);
16401640
COMPARE_SCALAR_FIELD(before);
16411641
COMPARE_SCALAR_FIELD(row);
1642-
if (strcmp(a->actions, b->actions) != 0) /* in-line string field */
1643-
return false;
1642+
COMPARE_SCALAR_FIELD(events);
16441643
COMPARE_SCALAR_FIELD(isconstraint);
16451644
COMPARE_SCALAR_FIELD(deferrable);
16461645
COMPARE_SCALAR_FIELD(initdeferred);

src/backend/parser/gram.y

+14-25
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.664 2009/05/27 20:42:29 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.665 2009/06/18 01:27:02 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -53,6 +53,7 @@
5353

5454
#include "catalog/index.h"
5555
#include "catalog/namespace.h"
56+
#include "catalog/pg_trigger.h"
5657
#include "commands/defrem.h"
5758
#include "nodes/makefuncs.h"
5859
#include "nodes/nodeFuncs.h"
@@ -244,7 +245,7 @@ static TypeName *TableFuncTypeName(List *columns);
244245
%type <boolean> TriggerActionTime TriggerForSpec opt_trusted opt_restart_seqs
245246
%type <str> opt_lancompiler
246247

247-
%type <str> TriggerEvents
248+
%type <ival> TriggerEvents TriggerOneEvent
248249
%type <value> TriggerFuncArg
249250

250251
%type <str> relation_name copy_file_name
@@ -266,7 +267,6 @@ static TypeName *TableFuncTypeName(List *columns);
266267
%type <privtarget> privilege_target
267268
%type <funwithargs> function_with_argtypes
268269
%type <list> function_with_argtypes_list
269-
%type <chr> TriggerOneEvent
270270

271271
%type <list> stmtblock stmtmulti
272272
OptTableElementList TableElementList OptInherit definition
@@ -3133,7 +3133,7 @@ CreateTrigStmt:
31333133
n->args = $13;
31343134
n->before = $4;
31353135
n->row = $8;
3136-
memcpy(n->actions, $5, 4);
3136+
n->events = $5;
31373137
n->isconstraint = FALSE;
31383138
n->deferrable = FALSE;
31393139
n->initdeferred = FALSE;
@@ -3153,11 +3153,10 @@ CreateTrigStmt:
31533153
n->args = $18;
31543154
n->before = FALSE;
31553155
n->row = TRUE;
3156-
memcpy(n->actions, $6, 4);
3156+
n->events = $6;
31573157
n->isconstraint = TRUE;
31583158
n->deferrable = ($10 & 1) != 0;
31593159
n->initdeferred = ($10 & 2) != 0;
3160-
31613160
n->constrrel = $9;
31623161
$$ = (Node *)n;
31633162
}
@@ -3170,30 +3169,20 @@ TriggerActionTime:
31703169

31713170
TriggerEvents:
31723171
TriggerOneEvent
3172+
{ $$ = $1; }
3173+
| TriggerEvents OR TriggerOneEvent
31733174
{
3174-
char *e = palloc(4);
3175-
e[0] = $1; e[1] = '\0';
3176-
$$ = e;
3177-
}
3178-
| TriggerOneEvent OR TriggerOneEvent
3179-
{
3180-
char *e = palloc(4);
3181-
e[0] = $1; e[1] = $3; e[2] = '\0';
3182-
$$ = e;
3183-
}
3184-
| TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
3185-
{
3186-
char *e = palloc(4);
3187-
e[0] = $1; e[1] = $3; e[2] = $5; e[3] = '\0';
3188-
$$ = e;
3175+
if ($1 & $3)
3176+
yyerror("duplicate trigger events specified");
3177+
$$ = $1 | $3;
31893178
}
31903179
;
31913180

31923181
TriggerOneEvent:
3193-
INSERT { $$ = 'i'; }
3194-
| DELETE_P { $$ = 'd'; }
3195-
| UPDATE { $$ = 'u'; }
3196-
| TRUNCATE { $$ = 't'; }
3182+
INSERT { $$ = TRIGGER_TYPE_INSERT; }
3183+
| DELETE_P { $$ = TRIGGER_TYPE_DELETE; }
3184+
| UPDATE { $$ = TRIGGER_TYPE_UPDATE; }
3185+
| TRUNCATE { $$ = TRIGGER_TYPE_TRUNCATE; }
31973186
;
31983187

31993188
TriggerForSpec:

src/include/nodes/parsenodes.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
1414
* Portions Copyright (c) 1994, Regents of the University of California
1515
*
16-
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.394 2009/06/11 14:49:11 momjian Exp $
16+
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.395 2009/06/18 01:27:02 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -1551,7 +1551,8 @@ typedef struct CreateTrigStmt
15511551
List *args; /* list of (T_String) Values or NIL */
15521552
bool before; /* BEFORE/AFTER */
15531553
bool row; /* ROW/STATEMENT */
1554-
char actions[4]; /* 1 to 3 of 'i', 'u', 'd', + trailing \0 */
1554+
/* events uses the TRIGGER_TYPE bits defined in catalog/pg_trigger.h */
1555+
int16 events; /* INSERT/UPDATE/DELETE/TRUNCATE */
15551556

15561557
/* The following are used for referential */
15571558
/* integrity constraint triggers */

0 commit comments

Comments
 (0)