]> granicus.if.org Git - postgresql/blob - src/backend/commands/trigger.c
Repair "Halloween problem" in EvalPlanQual: a tuple that's been inserted by
[postgresql] / src / backend / commands / trigger.c
1 /*-------------------------------------------------------------------------
2  *
3  * trigger.c
4  *        PostgreSQL TRIGGERs support code.
5  *
6  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  *        $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.199 2006/01/12 21:48:52 tgl Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15
16 #include "access/genam.h"
17 #include "access/heapam.h"
18 #include "access/xact.h"
19 #include "catalog/catalog.h"
20 #include "catalog/dependency.h"
21 #include "catalog/indexing.h"
22 #include "catalog/namespace.h"
23 #include "catalog/pg_language.h"
24 #include "catalog/pg_proc.h"
25 #include "catalog/pg_trigger.h"
26 #include "catalog/pg_type.h"
27 #include "commands/defrem.h"
28 #include "commands/trigger.h"
29 #include "executor/executor.h"
30 #include "executor/instrument.h"
31 #include "miscadmin.h"
32 #include "nodes/makefuncs.h"
33 #include "parser/parse_func.h"
34 #include "utils/acl.h"
35 #include "utils/builtins.h"
36 #include "utils/fmgroids.h"
37 #include "utils/inval.h"
38 #include "utils/lsyscache.h"
39 #include "utils/memutils.h"
40 #include "utils/syscache.h"
41
42
43 static void InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx);
44 static HeapTuple GetTupleForTrigger(EState *estate,
45                                    ResultRelInfo *relinfo,
46                                    ItemPointer tid,
47                                    CommandId cid,
48                                    TupleTableSlot **newSlot);
49 static HeapTuple ExecCallTriggerFunc(TriggerData *trigdata,
50                                         int tgindx,
51                                         FmgrInfo *finfo,
52                                         Instrumentation *instr,
53                                         MemoryContext per_tuple_context);
54 static void AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event,
55                                           bool row_trigger, HeapTuple oldtup, HeapTuple newtup);
56
57
58 /*
59  * Create a trigger.  Returns the OID of the created trigger.
60  *
61  * forConstraint, if true, says that this trigger is being created to
62  * implement a constraint.      The caller will then be expected to make
63  * a pg_depend entry linking the trigger to that constraint (and thereby
64  * to the owning relation(s)).
65  */
66 Oid
67 CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
68 {
69         int16           tgtype;
70         int2vector *tgattr;
71         Datum           values[Natts_pg_trigger];
72         char            nulls[Natts_pg_trigger];
73         Relation        rel;
74         AclResult       aclresult;
75         Relation        tgrel;
76         SysScanDesc tgscan;
77         ScanKeyData key;
78         Relation        pgrel;
79         HeapTuple       tuple;
80         Oid                     fargtypes[1];   /* dummy */
81         Oid                     funcoid;
82         Oid                     funcrettype;
83         Oid                     trigoid;
84         int                     found = 0;
85         int                     i;
86         char            constrtrigname[NAMEDATALEN];
87         char       *trigname;
88         char       *constrname;
89         Oid                     constrrelid = InvalidOid;
90         ObjectAddress myself,
91                                 referenced;
92
93         rel = heap_openrv(stmt->relation, AccessExclusiveLock);
94
95         if (stmt->constrrel != NULL)
96                 constrrelid = RangeVarGetRelid(stmt->constrrel, false);
97         else if (stmt->isconstraint)
98         {
99                 /*
100                  * If this trigger is a constraint (and a foreign key one) then we
101                  * really need a constrrelid.  Since we don't have one, we'll try to
102                  * generate one from the argument information.
103                  *
104                  * This is really just a workaround for a long-ago pg_dump bug that
105                  * omitted the FROM clause in dumped CREATE CONSTRAINT TRIGGER
106                  * commands.  We don't want to bomb out completely here if we can't
107                  * determine the correct relation, because that would prevent loading
108                  * the dump file.  Instead, NOTICE here and ERROR in the trigger.
109                  */
110                 bool            needconstrrelid = false;
111                 void       *elem = NULL;
112
113                 if (strncmp(strVal(lfirst(list_tail((stmt->funcname)))), "RI_FKey_check_", 14) == 0)
114                 {
115                         /* A trigger on FK table. */
116                         needconstrrelid = true;
117                         if (list_length(stmt->args) > RI_PK_RELNAME_ARGNO)
118                                 elem = list_nth(stmt->args, RI_PK_RELNAME_ARGNO);
119                 }
120                 else if (strncmp(strVal(lfirst(list_tail((stmt->funcname)))), "RI_FKey_", 8) == 0)
121                 {
122                         /* A trigger on PK table. */
123                         needconstrrelid = true;
124                         if (list_length(stmt->args) > RI_FK_RELNAME_ARGNO)
125                                 elem = list_nth(stmt->args, RI_FK_RELNAME_ARGNO);
126                 }
127                 if (elem != NULL)
128                 {
129                         RangeVar   *rel = makeRangeVar(NULL, strVal(elem));
130
131                         constrrelid = RangeVarGetRelid(rel, true);
132                 }
133                 if (needconstrrelid && constrrelid == InvalidOid)
134                         ereport(NOTICE,
135                                         (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
136                                          errmsg("could not determine referenced table for constraint \"%s\"",
137                                                         stmt->trigname)));
138         }
139
140         if (rel->rd_rel->relkind != RELKIND_RELATION)
141                 ereport(ERROR,
142                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
143                                  errmsg("\"%s\" is not a table",
144                                                 RelationGetRelationName(rel))));
145
146         if (!allowSystemTableMods && IsSystemRelation(rel))
147                 ereport(ERROR,
148                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
149                                  errmsg("permission denied: \"%s\" is a system catalog",
150                                                 RelationGetRelationName(rel))));
151
152         /* permission checks */
153
154         if (stmt->isconstraint)
155         {
156                 /* foreign key constraint trigger */
157
158                 aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
159                                                                           ACL_REFERENCES);
160                 if (aclresult != ACLCHECK_OK)
161                         aclcheck_error(aclresult, ACL_KIND_CLASS,
162                                                    RelationGetRelationName(rel));
163                 if (constrrelid != InvalidOid)
164                 {
165                         aclresult = pg_class_aclcheck(constrrelid, GetUserId(),
166                                                                                   ACL_REFERENCES);
167                         if (aclresult != ACLCHECK_OK)
168                                 aclcheck_error(aclresult, ACL_KIND_CLASS,
169                                                            get_rel_name(constrrelid));
170                 }
171         }
172         else
173         {
174                 /* real trigger */
175                 aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
176                                                                           ACL_TRIGGER);
177                 if (aclresult != ACLCHECK_OK)
178                         aclcheck_error(aclresult, ACL_KIND_CLASS,
179                                                    RelationGetRelationName(rel));
180         }
181
182         /*
183          * Generate the trigger's OID now, so that we can use it in the name if
184          * needed.
185          */
186         tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
187
188         trigoid = GetNewOid(tgrel);
189
190         /*
191          * If trigger is an RI constraint, use specified trigger name as
192          * constraint name and build a unique trigger name instead. This is mainly
193          * for backwards compatibility with CREATE CONSTRAINT TRIGGER commands.
194          */
195         if (stmt->isconstraint)
196         {
197                 snprintf(constrtrigname, sizeof(constrtrigname),
198                                  "RI_ConstraintTrigger_%u", trigoid);
199                 trigname = constrtrigname;
200                 constrname = stmt->trigname;
201         }
202         else
203         {
204                 trigname = stmt->trigname;
205                 constrname = "";
206         }
207
208         TRIGGER_CLEAR_TYPE(tgtype);
209         if (stmt->before)
210                 TRIGGER_SETT_BEFORE(tgtype);
211         if (stmt->row)
212                 TRIGGER_SETT_ROW(tgtype);
213
214         for (i = 0; stmt->actions[i]; i++)
215         {
216                 switch (stmt->actions[i])
217                 {
218                         case 'i':
219                                 if (TRIGGER_FOR_INSERT(tgtype))
220                                         ereport(ERROR,
221                                                         (errcode(ERRCODE_SYNTAX_ERROR),
222                                                          errmsg("multiple INSERT events specified")));
223                                 TRIGGER_SETT_INSERT(tgtype);
224                                 break;
225                         case 'd':
226                                 if (TRIGGER_FOR_DELETE(tgtype))
227                                         ereport(ERROR,
228                                                         (errcode(ERRCODE_SYNTAX_ERROR),
229                                                          errmsg("multiple DELETE events specified")));
230                                 TRIGGER_SETT_DELETE(tgtype);
231                                 break;
232                         case 'u':
233                                 if (TRIGGER_FOR_UPDATE(tgtype))
234                                         ereport(ERROR,
235                                                         (errcode(ERRCODE_SYNTAX_ERROR),
236                                                          errmsg("multiple UPDATE events specified")));
237                                 TRIGGER_SETT_UPDATE(tgtype);
238                                 break;
239                         default:
240                                 elog(ERROR, "unrecognized trigger event: %d",
241                                          (int) stmt->actions[i]);
242                                 break;
243                 }
244         }
245
246         /*
247          * Scan pg_trigger for existing triggers on relation.  We do this mainly
248          * because we must count them; a secondary benefit is to give a nice error
249          * message if there's already a trigger of the same name. (The unique
250          * index on tgrelid/tgname would complain anyway.)
251          *
252          * NOTE that this is cool only because we have AccessExclusiveLock on the
253          * relation, so the trigger set won't be changing underneath us.
254          */
255         ScanKeyInit(&key,
256                                 Anum_pg_trigger_tgrelid,
257                                 BTEqualStrategyNumber, F_OIDEQ,
258                                 ObjectIdGetDatum(RelationGetRelid(rel)));
259         tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
260                                                                 SnapshotNow, 1, &key);
261         while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
262         {
263                 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple);
264
265                 if (namestrcmp(&(pg_trigger->tgname), trigname) == 0)
266                         ereport(ERROR,
267                                         (errcode(ERRCODE_DUPLICATE_OBJECT),
268                                   errmsg("trigger \"%s\" for relation \"%s\" already exists",
269                                                  trigname, stmt->relation->relname)));
270                 found++;
271         }
272         systable_endscan(tgscan);
273
274         /*
275          * Find and validate the trigger function.
276          */
277         funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
278         funcrettype = get_func_rettype(funcoid);
279         if (funcrettype != TRIGGEROID)
280         {
281                 /*
282                  * We allow OPAQUE just so we can load old dump files.  When we see a
283                  * trigger function declared OPAQUE, change it to TRIGGER.
284                  */
285                 if (funcrettype == OPAQUEOID)
286                 {
287                         ereport(WARNING,
288                                         (errmsg("changing return type of function %s from \"opaque\" to \"trigger\"",
289                                                         NameListToString(stmt->funcname))));
290                         SetFunctionReturnType(funcoid, TRIGGEROID);
291                 }
292                 else
293                         ereport(ERROR,
294                                         (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
295                                          errmsg("function %s must return type \"trigger\"",
296                                                         NameListToString(stmt->funcname))));
297         }
298
299         /*
300          * Build the new pg_trigger tuple.
301          */
302         MemSet(nulls, ' ', Natts_pg_trigger * sizeof(char));
303
304         values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
305         values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
306                                                                                                   CStringGetDatum(trigname));
307         values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(funcoid);
308         values[Anum_pg_trigger_tgtype - 1] = Int16GetDatum(tgtype);
309         values[Anum_pg_trigger_tgenabled - 1] = BoolGetDatum(true);
310         values[Anum_pg_trigger_tgisconstraint - 1] = BoolGetDatum(stmt->isconstraint);
311         values[Anum_pg_trigger_tgconstrname - 1] = DirectFunctionCall1(namein,
312                                                                                                 CStringGetDatum(constrname));
313         values[Anum_pg_trigger_tgconstrrelid - 1] = ObjectIdGetDatum(constrrelid);
314         values[Anum_pg_trigger_tgdeferrable - 1] = BoolGetDatum(stmt->deferrable);
315         values[Anum_pg_trigger_tginitdeferred - 1] = BoolGetDatum(stmt->initdeferred);
316
317         if (stmt->args)
318         {
319                 ListCell   *le;
320                 char       *args;
321                 int16           nargs = list_length(stmt->args);
322                 int                     len = 0;
323
324                 foreach(le, stmt->args)
325                 {
326                         char       *ar = strVal(lfirst(le));
327
328                         len += strlen(ar) + 4;
329                         for (; *ar; ar++)
330                         {
331                                 if (*ar == '\\')
332                                         len++;
333                         }
334                 }
335                 args = (char *) palloc(len + 1);
336                 args[0] = '\0';
337                 foreach(le, stmt->args)
338                 {
339                         char       *s = strVal(lfirst(le));
340                         char       *d = args + strlen(args);
341
342                         while (*s)
343                         {
344                                 if (*s == '\\')
345                                         *d++ = '\\';
346                                 *d++ = *s++;
347                         }
348                         strcpy(d, "\\000");
349                 }
350                 values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(nargs);
351                 values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
352                                                                                                           CStringGetDatum(args));
353         }
354         else
355         {
356                 values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(0);
357                 values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
358                                                                                                                 CStringGetDatum(""));
359         }
360         /* tgattr is currently always a zero-length array */
361         tgattr = buildint2vector(NULL, 0);
362         values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);
363
364         tuple = heap_formtuple(tgrel->rd_att, values, nulls);
365
366         /* force tuple to have the desired OID */
367         HeapTupleSetOid(tuple, trigoid);
368
369         /*
370          * Insert tuple into pg_trigger.
371          */
372         simple_heap_insert(tgrel, tuple);
373
374         CatalogUpdateIndexes(tgrel, tuple);
375
376         myself.classId = TriggerRelationId;
377         myself.objectId = trigoid;
378         myself.objectSubId = 0;
379
380         heap_freetuple(tuple);
381         heap_close(tgrel, RowExclusiveLock);
382
383         pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
384         pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1]));
385
386         /*
387          * Update relation's pg_class entry.  Crucial side-effect: other backends
388          * (and this one too!) are sent SI message to make them rebuild relcache
389          * entries.
390          */
391         pgrel = heap_open(RelationRelationId, RowExclusiveLock);
392         tuple = SearchSysCacheCopy(RELOID,
393                                                            ObjectIdGetDatum(RelationGetRelid(rel)),
394                                                            0, 0, 0);
395         if (!HeapTupleIsValid(tuple))
396                 elog(ERROR, "cache lookup failed for relation %u",
397                          RelationGetRelid(rel));
398
399         ((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;
400
401         simple_heap_update(pgrel, &tuple->t_self, tuple);
402
403         CatalogUpdateIndexes(pgrel, tuple);
404
405         heap_freetuple(tuple);
406         heap_close(pgrel, RowExclusiveLock);
407
408         /*
409          * We used to try to update the rel's relcache entry here, but that's
410          * fairly pointless since it will happen as a byproduct of the upcoming
411          * CommandCounterIncrement...
412          */
413
414         /*
415          * Record dependencies for trigger.  Always place a normal dependency on
416          * the function.  If we are doing this in response to an explicit CREATE
417          * TRIGGER command, also make trigger be auto-dropped if its relation is
418          * dropped or if the FK relation is dropped.  (Auto drop is compatible
419          * with our pre-7.3 behavior.)  If the trigger is being made for a
420          * constraint, we can skip the relation links; the dependency on the
421          * constraint will indirectly depend on the relations.
422          */
423         referenced.classId = ProcedureRelationId;
424         referenced.objectId = funcoid;
425         referenced.objectSubId = 0;
426         recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
427
428         if (!forConstraint)
429         {
430                 referenced.classId = RelationRelationId;
431                 referenced.objectId = RelationGetRelid(rel);
432                 referenced.objectSubId = 0;
433                 recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
434                 if (constrrelid != InvalidOid)
435                 {
436                         referenced.classId = RelationRelationId;
437                         referenced.objectId = constrrelid;
438                         referenced.objectSubId = 0;
439                         recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
440                 }
441         }
442
443         /* Keep lock on target rel until end of xact */
444         heap_close(rel, NoLock);
445
446         return trigoid;
447 }
448
449 /*
450  * DropTrigger - drop an individual trigger by name
451  */
452 void
453 DropTrigger(Oid relid, const char *trigname, DropBehavior behavior)
454 {
455         Relation        tgrel;
456         ScanKeyData skey[2];
457         SysScanDesc tgscan;
458         HeapTuple       tup;
459         ObjectAddress object;
460
461         /*
462          * Find the trigger, verify permissions, set up object address
463          */
464         tgrel = heap_open(TriggerRelationId, AccessShareLock);
465
466         ScanKeyInit(&skey[0],
467                                 Anum_pg_trigger_tgrelid,
468                                 BTEqualStrategyNumber, F_OIDEQ,
469                                 ObjectIdGetDatum(relid));
470
471         ScanKeyInit(&skey[1],
472                                 Anum_pg_trigger_tgname,
473                                 BTEqualStrategyNumber, F_NAMEEQ,
474                                 CStringGetDatum(trigname));
475
476         tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
477                                                                 SnapshotNow, 2, skey);
478
479         tup = systable_getnext(tgscan);
480
481         if (!HeapTupleIsValid(tup))
482                 ereport(ERROR,
483                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
484                                  errmsg("trigger \"%s\" for table \"%s\" does not exist",
485                                                 trigname, get_rel_name(relid))));
486
487         if (!pg_class_ownercheck(relid, GetUserId()))
488                 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
489                                            get_rel_name(relid));
490
491         object.classId = TriggerRelationId;
492         object.objectId = HeapTupleGetOid(tup);
493         object.objectSubId = 0;
494
495         systable_endscan(tgscan);
496         heap_close(tgrel, AccessShareLock);
497
498         /*
499          * Do the deletion
500          */
501         performDeletion(&object, behavior);
502 }
503
504 /*
505  * Guts of trigger deletion.
506  */
507 void
508 RemoveTriggerById(Oid trigOid)
509 {
510         Relation        tgrel;
511         SysScanDesc tgscan;
512         ScanKeyData skey[1];
513         HeapTuple       tup;
514         Oid                     relid;
515         Relation        rel;
516         Relation        pgrel;
517         HeapTuple       tuple;
518         Form_pg_class classForm;
519
520         tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
521
522         /*
523          * Find the trigger to delete.
524          */
525         ScanKeyInit(&skey[0],
526                                 ObjectIdAttributeNumber,
527                                 BTEqualStrategyNumber, F_OIDEQ,
528                                 ObjectIdGetDatum(trigOid));
529
530         tgscan = systable_beginscan(tgrel, TriggerOidIndexId, true,
531                                                                 SnapshotNow, 1, skey);
532
533         tup = systable_getnext(tgscan);
534         if (!HeapTupleIsValid(tup))
535                 elog(ERROR, "could not find tuple for trigger %u", trigOid);
536
537         /*
538          * Open and exclusive-lock the relation the trigger belongs to.
539          */
540         relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid;
541
542         rel = heap_open(relid, AccessExclusiveLock);
543
544         if (rel->rd_rel->relkind != RELKIND_RELATION)
545                 ereport(ERROR,
546                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
547                                  errmsg("\"%s\" is not a table",
548                                                 RelationGetRelationName(rel))));
549
550         if (!allowSystemTableMods && IsSystemRelation(rel))
551                 ereport(ERROR,
552                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
553                                  errmsg("permission denied: \"%s\" is a system catalog",
554                                                 RelationGetRelationName(rel))));
555
556         /*
557          * Delete the pg_trigger tuple.
558          */
559         simple_heap_delete(tgrel, &tup->t_self);
560
561         systable_endscan(tgscan);
562         heap_close(tgrel, RowExclusiveLock);
563
564         /*
565          * Update relation's pg_class entry.  Crucial side-effect: other backends
566          * (and this one too!) are sent SI message to make them rebuild relcache
567          * entries.
568          *
569          * Note this is OK only because we have AccessExclusiveLock on the rel, so
570          * no one else is creating/deleting triggers on this rel at the same time.
571          */
572         pgrel = heap_open(RelationRelationId, RowExclusiveLock);
573         tuple = SearchSysCacheCopy(RELOID,
574                                                            ObjectIdGetDatum(relid),
575                                                            0, 0, 0);
576         if (!HeapTupleIsValid(tuple))
577                 elog(ERROR, "cache lookup failed for relation %u", relid);
578         classForm = (Form_pg_class) GETSTRUCT(tuple);
579
580         if (classForm->reltriggers == 0)        /* should not happen */
581                 elog(ERROR, "relation \"%s\" has reltriggers = 0",
582                          RelationGetRelationName(rel));
583         classForm->reltriggers--;
584
585         simple_heap_update(pgrel, &tuple->t_self, tuple);
586
587         CatalogUpdateIndexes(pgrel, tuple);
588
589         heap_freetuple(tuple);
590
591         heap_close(pgrel, RowExclusiveLock);
592
593         /* Keep lock on trigger's rel until end of xact */
594         heap_close(rel, NoLock);
595 }
596
597 /*
598  *              renametrig              - changes the name of a trigger on a relation
599  *
600  *              trigger name is changed in trigger catalog.
601  *              No record of the previous name is kept.
602  *
603  *              get proper relrelation from relation catalog (if not arg)
604  *              scan trigger catalog
605  *                              for name conflict (within rel)
606  *                              for original trigger (if not arg)
607  *              modify tgname in trigger tuple
608  *              update row in catalog
609  */
610 void
611 renametrig(Oid relid,
612                    const char *oldname,
613                    const char *newname)
614 {
615         Relation        targetrel;
616         Relation        tgrel;
617         HeapTuple       tuple;
618         SysScanDesc tgscan;
619         ScanKeyData key[2];
620
621         /*
622          * Grab an exclusive lock on the target table, which we will NOT release
623          * until end of transaction.
624          */
625         targetrel = heap_open(relid, AccessExclusiveLock);
626
627         /*
628          * Scan pg_trigger twice for existing triggers on relation.  We do this in
629          * order to ensure a trigger does not exist with newname (The unique index
630          * on tgrelid/tgname would complain anyway) and to ensure a trigger does
631          * exist with oldname.
632          *
633          * NOTE that this is cool only because we have AccessExclusiveLock on the
634          * relation, so the trigger set won't be changing underneath us.
635          */
636         tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
637
638         /*
639          * First pass -- look for name conflict
640          */
641         ScanKeyInit(&key[0],
642                                 Anum_pg_trigger_tgrelid,
643                                 BTEqualStrategyNumber, F_OIDEQ,
644                                 ObjectIdGetDatum(relid));
645         ScanKeyInit(&key[1],
646                                 Anum_pg_trigger_tgname,
647                                 BTEqualStrategyNumber, F_NAMEEQ,
648                                 PointerGetDatum(newname));
649         tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
650                                                                 SnapshotNow, 2, key);
651         if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
652                 ereport(ERROR,
653                                 (errcode(ERRCODE_DUPLICATE_OBJECT),
654                                  errmsg("trigger \"%s\" for relation \"%s\" already exists",
655                                                 newname, RelationGetRelationName(targetrel))));
656         systable_endscan(tgscan);
657
658         /*
659          * Second pass -- look for trigger existing with oldname and update
660          */
661         ScanKeyInit(&key[0],
662                                 Anum_pg_trigger_tgrelid,
663                                 BTEqualStrategyNumber, F_OIDEQ,
664                                 ObjectIdGetDatum(relid));
665         ScanKeyInit(&key[1],
666                                 Anum_pg_trigger_tgname,
667                                 BTEqualStrategyNumber, F_NAMEEQ,
668                                 PointerGetDatum(oldname));
669         tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
670                                                                 SnapshotNow, 2, key);
671         if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
672         {
673                 /*
674                  * Update pg_trigger tuple with new tgname.
675                  */
676                 tuple = heap_copytuple(tuple);  /* need a modifiable copy */
677
678                 namestrcpy(&((Form_pg_trigger) GETSTRUCT(tuple))->tgname, newname);
679
680                 simple_heap_update(tgrel, &tuple->t_self, tuple);
681
682                 /* keep system catalog indexes current */
683                 CatalogUpdateIndexes(tgrel, tuple);
684
685                 /*
686                  * Invalidate relation's relcache entry so that other backends (and
687                  * this one too!) are sent SI message to make them rebuild relcache
688                  * entries.  (Ideally this should happen automatically...)
689                  */
690                 CacheInvalidateRelcache(targetrel);
691         }
692         else
693         {
694                 ereport(ERROR,
695                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
696                                  errmsg("trigger \"%s\" for table \"%s\" does not exist",
697                                                 oldname, RelationGetRelationName(targetrel))));
698         }
699
700         systable_endscan(tgscan);
701
702         heap_close(tgrel, RowExclusiveLock);
703
704         /*
705          * Close rel, but keep exclusive lock!
706          */
707         heap_close(targetrel, NoLock);
708 }
709
710
711 /*
712  * EnableDisableTrigger()
713  *
714  *      Called by ALTER TABLE ENABLE/DISABLE TRIGGER
715  *      to change 'tgenabled' flag for the specified trigger(s)
716  *
717  * rel: relation to process (caller must hold suitable lock on it)
718  * tgname: trigger to process, or NULL to scan all triggers
719  * enable: new value for tgenabled flag
720  * skip_system: if true, skip "system" triggers (constraint triggers)
721  *
722  * Caller should have checked permissions for the table; here we also
723  * enforce that superuser privilege is required to alter the state of
724  * system triggers
725  */
726 void
727 EnableDisableTrigger(Relation rel, const char *tgname,
728                                          bool enable, bool skip_system)
729 {
730         Relation        tgrel;
731         int                     nkeys;
732         ScanKeyData keys[2];
733         SysScanDesc tgscan;
734         HeapTuple       tuple;
735         bool            found;
736         bool            changed;
737
738         /* Scan the relevant entries in pg_triggers */
739         tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
740
741         ScanKeyInit(&keys[0],
742                                 Anum_pg_trigger_tgrelid,
743                                 BTEqualStrategyNumber, F_OIDEQ,
744                                 ObjectIdGetDatum(RelationGetRelid(rel)));
745         if (tgname)
746         {
747                 ScanKeyInit(&keys[1],
748                                         Anum_pg_trigger_tgname,
749                                         BTEqualStrategyNumber, F_NAMEEQ,
750                                         CStringGetDatum(tgname));
751                 nkeys = 2;
752         }
753         else
754                 nkeys = 1;
755
756         tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
757                                                                 SnapshotNow, nkeys, keys);
758
759         found = changed = false;
760
761         while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
762         {
763                 Form_pg_trigger oldtrig = (Form_pg_trigger) GETSTRUCT(tuple);
764
765                 if (oldtrig->tgisconstraint)
766                 {
767                         /* system trigger ... ok to process? */
768                         if (skip_system)
769                                 continue;
770                         if (!superuser())
771                                 ereport(ERROR,
772                                                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
773                                           errmsg("permission denied: \"%s\" is a system trigger",
774                                                          NameStr(oldtrig->tgname))));
775                 }
776
777                 found = true;
778
779                 if (oldtrig->tgenabled != enable)
780                 {
781                         /* need to change this one ... make a copy to scribble on */
782                         HeapTuple       newtup = heap_copytuple(tuple);
783                         Form_pg_trigger newtrig = (Form_pg_trigger) GETSTRUCT(newtup);
784
785                         newtrig->tgenabled = enable;
786
787                         simple_heap_update(tgrel, &newtup->t_self, newtup);
788
789                         /* Keep catalog indexes current */
790                         CatalogUpdateIndexes(tgrel, newtup);
791
792                         heap_freetuple(newtup);
793
794                         changed = true;
795                 }
796         }
797
798         systable_endscan(tgscan);
799
800         heap_close(tgrel, RowExclusiveLock);
801
802         if (tgname && !found)
803                 ereport(ERROR,
804                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
805                                  errmsg("trigger \"%s\" for table \"%s\" does not exist",
806                                                 tgname, RelationGetRelationName(rel))));
807
808         /*
809          * If we changed anything, broadcast a SI inval message to force each
810          * backend (including our own!) to rebuild relation's relcache entry.
811          * Otherwise they will fail to apply the change promptly.
812          */
813         if (changed)
814                 CacheInvalidateRelcache(rel);
815 }
816
817
818 /*
819  * Build trigger data to attach to the given relcache entry.
820  *
821  * Note that trigger data attached to a relcache entry must be stored in
822  * CacheMemoryContext to ensure it survives as long as the relcache entry.
823  * But we should be running in a less long-lived working context.  To avoid
824  * leaking cache memory if this routine fails partway through, we build a
825  * temporary TriggerDesc in working memory and then copy the completed
826  * structure into cache memory.
827  */
828 void
829 RelationBuildTriggers(Relation relation)
830 {
831         TriggerDesc *trigdesc;
832         int                     ntrigs = relation->rd_rel->reltriggers;
833         Trigger    *triggers;
834         int                     found = 0;
835         Relation        tgrel;
836         ScanKeyData skey;
837         SysScanDesc tgscan;
838         HeapTuple       htup;
839         MemoryContext oldContext;
840
841         Assert(ntrigs > 0);                     /* else I should not have been called */
842
843         triggers = (Trigger *) palloc(ntrigs * sizeof(Trigger));
844
845         /*
846          * Note: since we scan the triggers using TriggerRelidNameIndexId, we will
847          * be reading the triggers in name order, except possibly during
848          * emergency-recovery operations (ie, IgnoreSystemIndexes). This in
849          * turn ensures that triggers will be fired in name order.
850          */
851         ScanKeyInit(&skey,
852                                 Anum_pg_trigger_tgrelid,
853                                 BTEqualStrategyNumber, F_OIDEQ,
854                                 ObjectIdGetDatum(RelationGetRelid(relation)));
855
856         tgrel = heap_open(TriggerRelationId, AccessShareLock);
857         tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true,
858                                                                 SnapshotNow, 1, &skey);
859
860         while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
861         {
862                 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
863                 Trigger    *build;
864
865                 if (found >= ntrigs)
866                         elog(ERROR, "too many trigger records found for relation \"%s\"",
867                                  RelationGetRelationName(relation));
868                 build = &(triggers[found]);
869
870                 build->tgoid = HeapTupleGetOid(htup);
871                 build->tgname = DatumGetCString(DirectFunctionCall1(nameout,
872                                                                                  NameGetDatum(&pg_trigger->tgname)));
873                 build->tgfoid = pg_trigger->tgfoid;
874                 build->tgtype = pg_trigger->tgtype;
875                 build->tgenabled = pg_trigger->tgenabled;
876                 build->tgisconstraint = pg_trigger->tgisconstraint;
877                 build->tgconstrrelid = pg_trigger->tgconstrrelid;
878                 build->tgdeferrable = pg_trigger->tgdeferrable;
879                 build->tginitdeferred = pg_trigger->tginitdeferred;
880                 build->tgnargs = pg_trigger->tgnargs;
881                 /* tgattr is first var-width field, so OK to access directly */
882                 build->tgnattr = pg_trigger->tgattr.dim1;
883                 if (build->tgnattr > 0)
884                 {
885                         build->tgattr = (int2 *) palloc(build->tgnattr * sizeof(int2));
886                         memcpy(build->tgattr, &(pg_trigger->tgattr.values),
887                                    build->tgnattr * sizeof(int2));
888                 }
889                 else
890                         build->tgattr = NULL;
891                 if (build->tgnargs > 0)
892                 {
893                         bytea      *val;
894                         bool            isnull;
895                         char       *p;
896                         int                     i;
897
898                         val = (bytea *)
899                                 DatumGetPointer(fastgetattr(htup,
900                                                                                         Anum_pg_trigger_tgargs,
901                                                                                         tgrel->rd_att, &isnull));
902                         if (isnull)
903                                 elog(ERROR, "tgargs is null in trigger for relation \"%s\"",
904                                          RelationGetRelationName(relation));
905                         p = (char *) VARDATA(val);
906                         build->tgargs = (char **) palloc(build->tgnargs * sizeof(char *));
907                         for (i = 0; i < build->tgnargs; i++)
908                         {
909                                 build->tgargs[i] = pstrdup(p);
910                                 p += strlen(p) + 1;
911                         }
912                 }
913                 else
914                         build->tgargs = NULL;
915
916                 found++;
917         }
918
919         systable_endscan(tgscan);
920         heap_close(tgrel, AccessShareLock);
921
922         if (found != ntrigs)
923                 elog(ERROR, "%d trigger record(s) not found for relation \"%s\"",
924                          ntrigs - found,
925                          RelationGetRelationName(relation));
926
927         /* Build trigdesc */
928         trigdesc = (TriggerDesc *) palloc0(sizeof(TriggerDesc));
929         trigdesc->triggers = triggers;
930         trigdesc->numtriggers = ntrigs;
931         for (found = 0; found < ntrigs; found++)
932                 InsertTrigger(trigdesc, &(triggers[found]), found);
933
934         /* Copy completed trigdesc into cache storage */
935         oldContext = MemoryContextSwitchTo(CacheMemoryContext);
936         relation->trigdesc = CopyTriggerDesc(trigdesc);
937         MemoryContextSwitchTo(oldContext);
938
939         /* Release working memory */
940         FreeTriggerDesc(trigdesc);
941 }
942
943 /*
944  * Insert the given trigger into the appropriate index list(s) for it
945  *
946  * To simplify storage management, we allocate each index list at the max
947  * possible size (trigdesc->numtriggers) if it's used at all.  This does
948  * not waste space permanently since we're only building a temporary
949  * trigdesc at this point.
950  */
951 static void
952 InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx)
953 {
954         uint16     *n;
955         int               **t,
956                           **tp;
957
958         if (TRIGGER_FOR_ROW(trigger->tgtype))
959         {
960                 /* ROW trigger */
961                 if (TRIGGER_FOR_BEFORE(trigger->tgtype))
962                 {
963                         n = trigdesc->n_before_row;
964                         t = trigdesc->tg_before_row;
965                 }
966                 else
967                 {
968                         n = trigdesc->n_after_row;
969                         t = trigdesc->tg_after_row;
970                 }
971         }
972         else
973         {
974                 /* STATEMENT trigger */
975                 if (TRIGGER_FOR_BEFORE(trigger->tgtype))
976                 {
977                         n = trigdesc->n_before_statement;
978                         t = trigdesc->tg_before_statement;
979                 }
980                 else
981                 {
982                         n = trigdesc->n_after_statement;
983                         t = trigdesc->tg_after_statement;
984                 }
985         }
986
987         if (TRIGGER_FOR_INSERT(trigger->tgtype))
988         {
989                 tp = &(t[TRIGGER_EVENT_INSERT]);
990                 if (*tp == NULL)
991                         *tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
992                 (*tp)[n[TRIGGER_EVENT_INSERT]] = indx;
993                 (n[TRIGGER_EVENT_INSERT])++;
994         }
995
996         if (TRIGGER_FOR_DELETE(trigger->tgtype))
997         {
998                 tp = &(t[TRIGGER_EVENT_DELETE]);
999                 if (*tp == NULL)
1000                         *tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
1001                 (*tp)[n[TRIGGER_EVENT_DELETE]] = indx;
1002                 (n[TRIGGER_EVENT_DELETE])++;
1003         }
1004
1005         if (TRIGGER_FOR_UPDATE(trigger->tgtype))
1006         {
1007                 tp = &(t[TRIGGER_EVENT_UPDATE]);
1008                 if (*tp == NULL)
1009                         *tp = (int *) palloc(trigdesc->numtriggers * sizeof(int));
1010                 (*tp)[n[TRIGGER_EVENT_UPDATE]] = indx;
1011                 (n[TRIGGER_EVENT_UPDATE])++;
1012         }
1013 }
1014
1015 /*
1016  * Copy a TriggerDesc data structure.
1017  *
1018  * The copy is allocated in the current memory context.
1019  */
1020 TriggerDesc *
1021 CopyTriggerDesc(TriggerDesc *trigdesc)
1022 {
1023         TriggerDesc *newdesc;
1024         uint16     *n;
1025         int               **t,
1026                            *tnew;
1027         Trigger    *trigger;
1028         int                     i;
1029
1030         if (trigdesc == NULL || trigdesc->numtriggers <= 0)
1031                 return NULL;
1032
1033         newdesc = (TriggerDesc *) palloc(sizeof(TriggerDesc));
1034         memcpy(newdesc, trigdesc, sizeof(TriggerDesc));
1035
1036         trigger = (Trigger *) palloc(trigdesc->numtriggers * sizeof(Trigger));
1037         memcpy(trigger, trigdesc->triggers,
1038                    trigdesc->numtriggers * sizeof(Trigger));
1039         newdesc->triggers = trigger;
1040
1041         for (i = 0; i < trigdesc->numtriggers; i++)
1042         {
1043                 trigger->tgname = pstrdup(trigger->tgname);
1044                 if (trigger->tgnattr > 0)
1045                 {
1046                         int2       *newattr;
1047
1048                         newattr = (int2 *) palloc(trigger->tgnattr * sizeof(int2));
1049                         memcpy(newattr, trigger->tgattr,
1050                                    trigger->tgnattr * sizeof(int2));
1051                         trigger->tgattr = newattr;
1052                 }
1053                 if (trigger->tgnargs > 0)
1054                 {
1055                         char      **newargs;
1056                         int16           j;
1057
1058                         newargs = (char **) palloc(trigger->tgnargs * sizeof(char *));
1059                         for (j = 0; j < trigger->tgnargs; j++)
1060                                 newargs[j] = pstrdup(trigger->tgargs[j]);
1061                         trigger->tgargs = newargs;
1062                 }
1063                 trigger++;
1064         }
1065
1066         n = newdesc->n_before_statement;
1067         t = newdesc->tg_before_statement;
1068         for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1069         {
1070                 if (n[i] > 0)
1071                 {
1072                         tnew = (int *) palloc(n[i] * sizeof(int));
1073                         memcpy(tnew, t[i], n[i] * sizeof(int));
1074                         t[i] = tnew;
1075                 }
1076                 else
1077                         t[i] = NULL;
1078         }
1079         n = newdesc->n_before_row;
1080         t = newdesc->tg_before_row;
1081         for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1082         {
1083                 if (n[i] > 0)
1084                 {
1085                         tnew = (int *) palloc(n[i] * sizeof(int));
1086                         memcpy(tnew, t[i], n[i] * sizeof(int));
1087                         t[i] = tnew;
1088                 }
1089                 else
1090                         t[i] = NULL;
1091         }
1092         n = newdesc->n_after_row;
1093         t = newdesc->tg_after_row;
1094         for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1095         {
1096                 if (n[i] > 0)
1097                 {
1098                         tnew = (int *) palloc(n[i] * sizeof(int));
1099                         memcpy(tnew, t[i], n[i] * sizeof(int));
1100                         t[i] = tnew;
1101                 }
1102                 else
1103                         t[i] = NULL;
1104         }
1105         n = newdesc->n_after_statement;
1106         t = newdesc->tg_after_statement;
1107         for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1108         {
1109                 if (n[i] > 0)
1110                 {
1111                         tnew = (int *) palloc(n[i] * sizeof(int));
1112                         memcpy(tnew, t[i], n[i] * sizeof(int));
1113                         t[i] = tnew;
1114                 }
1115                 else
1116                         t[i] = NULL;
1117         }
1118
1119         return newdesc;
1120 }
1121
1122 /*
1123  * Free a TriggerDesc data structure.
1124  */
1125 void
1126 FreeTriggerDesc(TriggerDesc *trigdesc)
1127 {
1128         int               **t;
1129         Trigger    *trigger;
1130         int                     i;
1131
1132         if (trigdesc == NULL)
1133                 return;
1134
1135         t = trigdesc->tg_before_statement;
1136         for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1137                 if (t[i] != NULL)
1138                         pfree(t[i]);
1139         t = trigdesc->tg_before_row;
1140         for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1141                 if (t[i] != NULL)
1142                         pfree(t[i]);
1143         t = trigdesc->tg_after_row;
1144         for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1145                 if (t[i] != NULL)
1146                         pfree(t[i]);
1147         t = trigdesc->tg_after_statement;
1148         for (i = 0; i < TRIGGER_NUM_EVENT_CLASSES; i++)
1149                 if (t[i] != NULL)
1150                         pfree(t[i]);
1151
1152         trigger = trigdesc->triggers;
1153         for (i = 0; i < trigdesc->numtriggers; i++)
1154         {
1155                 pfree(trigger->tgname);
1156                 if (trigger->tgnattr > 0)
1157                         pfree(trigger->tgattr);
1158                 if (trigger->tgnargs > 0)
1159                 {
1160                         while (--(trigger->tgnargs) >= 0)
1161                                 pfree(trigger->tgargs[trigger->tgnargs]);
1162                         pfree(trigger->tgargs);
1163                 }
1164                 trigger++;
1165         }
1166         pfree(trigdesc->triggers);
1167         pfree(trigdesc);
1168 }
1169
1170 /*
1171  * Compare two TriggerDesc structures for logical equality.
1172  */
1173 #ifdef NOT_USED
1174 bool
1175 equalTriggerDescs(TriggerDesc *trigdesc1, TriggerDesc *trigdesc2)
1176 {
1177         int                     i,
1178                                 j;
1179
1180         /*
1181          * We need not examine the "index" data, just the trigger array itself; if
1182          * we have the same triggers with the same types, the derived index data
1183          * should match.
1184          *
1185          * As of 7.3 we assume trigger set ordering is significant in the
1186          * comparison; so we just compare corresponding slots of the two sets.
1187          */
1188         if (trigdesc1 != NULL)
1189         {
1190                 if (trigdesc2 == NULL)
1191                         return false;
1192                 if (trigdesc1->numtriggers != trigdesc2->numtriggers)
1193                         return false;
1194                 for (i = 0; i < trigdesc1->numtriggers; i++)
1195                 {
1196                         Trigger    *trig1 = trigdesc1->triggers + i;
1197                         Trigger    *trig2 = trigdesc2->triggers + i;
1198
1199                         if (trig1->tgoid != trig2->tgoid)
1200                                 return false;
1201                         if (strcmp(trig1->tgname, trig2->tgname) != 0)
1202                                 return false;
1203                         if (trig1->tgfoid != trig2->tgfoid)
1204                                 return false;
1205                         if (trig1->tgtype != trig2->tgtype)
1206                                 return false;
1207                         if (trig1->tgenabled != trig2->tgenabled)
1208                                 return false;
1209                         if (trig1->tgisconstraint != trig2->tgisconstraint)
1210                                 return false;
1211                         if (trig1->tgconstrrelid != trig2->tgconstrrelid)
1212                                 return false;
1213                         if (trig1->tgdeferrable != trig2->tgdeferrable)
1214                                 return false;
1215                         if (trig1->tginitdeferred != trig2->tginitdeferred)
1216                                 return false;
1217                         if (trig1->tgnargs != trig2->tgnargs)
1218                                 return false;
1219                         if (trig1->tgnattr != trig2->tgnattr)
1220                                 return false;
1221                         if (trig1->tgnattr > 0 &&
1222                                 memcmp(trig1->tgattr, trig2->tgattr,
1223                                            trig1->tgnattr * sizeof(int2)) != 0)
1224                                 return false;
1225                         for (j = 0; j < trig1->tgnargs; j++)
1226                                 if (strcmp(trig1->tgargs[j], trig2->tgargs[j]) != 0)
1227                                         return false;
1228                 }
1229         }
1230         else if (trigdesc2 != NULL)
1231                 return false;
1232         return true;
1233 }
1234 #endif   /* NOT_USED */
1235
1236 /*
1237  * Call a trigger function.
1238  *
1239  *              trigdata: trigger descriptor.
1240  *              tgindx: trigger's index in finfo and instr arrays.
1241  *              finfo: array of cached trigger function call information.
1242  *              instr: optional array of EXPLAIN ANALYZE instrumentation state.
1243  *              per_tuple_context: memory context to execute the function in.
1244  *
1245  * Returns the tuple (or NULL) as returned by the function.
1246  */
1247 static HeapTuple
1248 ExecCallTriggerFunc(TriggerData *trigdata,
1249                                         int tgindx,
1250                                         FmgrInfo *finfo,
1251                                         Instrumentation *instr,
1252                                         MemoryContext per_tuple_context)
1253 {
1254         FunctionCallInfoData fcinfo;
1255         Datum           result;
1256         MemoryContext oldContext;
1257
1258         finfo += tgindx;
1259
1260         /*
1261          * We cache fmgr lookup info, to avoid making the lookup again on each
1262          * call.
1263          */
1264         if (finfo->fn_oid == InvalidOid)
1265                 fmgr_info(trigdata->tg_trigger->tgfoid, finfo);
1266
1267         Assert(finfo->fn_oid == trigdata->tg_trigger->tgfoid);
1268
1269         /*
1270          * If doing EXPLAIN ANALYZE, start charging time to this trigger.
1271          */
1272         if (instr)
1273                 InstrStartNode(instr + tgindx);
1274
1275         /*
1276          * Do the function evaluation in the per-tuple memory context, so that
1277          * leaked memory will be reclaimed once per tuple. Note in particular that
1278          * any new tuple created by the trigger function will live till the end of
1279          * the tuple cycle.
1280          */
1281         oldContext = MemoryContextSwitchTo(per_tuple_context);
1282
1283         /*
1284          * Call the function, passing no arguments but setting a context.
1285          */
1286         InitFunctionCallInfoData(fcinfo, finfo, 0, (Node *) trigdata, NULL);
1287
1288         result = FunctionCallInvoke(&fcinfo);
1289
1290         MemoryContextSwitchTo(oldContext);
1291
1292         /*
1293          * Trigger protocol allows function to return a null pointer, but NOT to
1294          * set the isnull result flag.
1295          */
1296         if (fcinfo.isnull)
1297                 ereport(ERROR,
1298                                 (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1299                                  errmsg("trigger function %u returned null value",
1300                                                 fcinfo.flinfo->fn_oid)));
1301
1302         /*
1303          * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
1304          * one "tuple returned" (really the number of firings).
1305          */
1306         if (instr)
1307                 InstrStopNode(instr + tgindx, true);
1308
1309         return (HeapTuple) DatumGetPointer(result);
1310 }
1311
1312 void
1313 ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo)
1314 {
1315         TriggerDesc *trigdesc;
1316         int                     ntrigs;
1317         int                *tgindx;
1318         int                     i;
1319         TriggerData LocTriggerData;
1320
1321         trigdesc = relinfo->ri_TrigDesc;
1322
1323         if (trigdesc == NULL)
1324                 return;
1325
1326         ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_INSERT];
1327         tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_INSERT];
1328
1329         if (ntrigs == 0)
1330                 return;
1331
1332         LocTriggerData.type = T_TriggerData;
1333         LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
1334                 TRIGGER_EVENT_BEFORE;
1335         LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1336         LocTriggerData.tg_trigtuple = NULL;
1337         LocTriggerData.tg_newtuple = NULL;
1338         LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1339         LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1340         for (i = 0; i < ntrigs; i++)
1341         {
1342                 Trigger    *trigger = &trigdesc->triggers[tgindx[i]];
1343                 HeapTuple       newtuple;
1344
1345                 if (!trigger->tgenabled)
1346                         continue;
1347                 LocTriggerData.tg_trigger = trigger;
1348                 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1349                                                                            tgindx[i],
1350                                                                            relinfo->ri_TrigFunctions,
1351                                                                            relinfo->ri_TrigInstrument,
1352                                                                            GetPerTupleMemoryContext(estate));
1353
1354                 if (newtuple)
1355                         ereport(ERROR,
1356                                         (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1357                                   errmsg("BEFORE STATEMENT trigger cannot return a value")));
1358         }
1359 }
1360
1361 void
1362 ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo)
1363 {
1364         TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1365
1366         if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_INSERT] > 0)
1367                 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_INSERT,
1368                                                           false, NULL, NULL);
1369 }
1370
1371 HeapTuple
1372 ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo,
1373                                          HeapTuple trigtuple)
1374 {
1375         TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1376         int                     ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_INSERT];
1377         int                *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_INSERT];
1378         HeapTuple       newtuple = trigtuple;
1379         HeapTuple       oldtuple;
1380         TriggerData LocTriggerData;
1381         int                     i;
1382
1383         LocTriggerData.type = T_TriggerData;
1384         LocTriggerData.tg_event = TRIGGER_EVENT_INSERT |
1385                 TRIGGER_EVENT_ROW |
1386                 TRIGGER_EVENT_BEFORE;
1387         LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1388         LocTriggerData.tg_newtuple = NULL;
1389         LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1390         for (i = 0; i < ntrigs; i++)
1391         {
1392                 Trigger    *trigger = &trigdesc->triggers[tgindx[i]];
1393
1394                 if (!trigger->tgenabled)
1395                         continue;
1396                 LocTriggerData.tg_trigtuple = oldtuple = newtuple;
1397                 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1398                 LocTriggerData.tg_trigger = trigger;
1399                 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1400                                                                            tgindx[i],
1401                                                                            relinfo->ri_TrigFunctions,
1402                                                                            relinfo->ri_TrigInstrument,
1403                                                                            GetPerTupleMemoryContext(estate));
1404                 if (oldtuple != newtuple && oldtuple != trigtuple)
1405                         heap_freetuple(oldtuple);
1406                 if (newtuple == NULL)
1407                         break;
1408         }
1409         return newtuple;
1410 }
1411
1412 void
1413 ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo,
1414                                          HeapTuple trigtuple)
1415 {
1416         TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1417
1418         if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0)
1419                 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_INSERT,
1420                                                           true, NULL, trigtuple);
1421 }
1422
1423 void
1424 ExecBSDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
1425 {
1426         TriggerDesc *trigdesc;
1427         int                     ntrigs;
1428         int                *tgindx;
1429         int                     i;
1430         TriggerData LocTriggerData;
1431
1432         trigdesc = relinfo->ri_TrigDesc;
1433
1434         if (trigdesc == NULL)
1435                 return;
1436
1437         ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_DELETE];
1438         tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_DELETE];
1439
1440         if (ntrigs == 0)
1441                 return;
1442
1443         LocTriggerData.type = T_TriggerData;
1444         LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
1445                 TRIGGER_EVENT_BEFORE;
1446         LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1447         LocTriggerData.tg_trigtuple = NULL;
1448         LocTriggerData.tg_newtuple = NULL;
1449         LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1450         LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1451         for (i = 0; i < ntrigs; i++)
1452         {
1453                 Trigger    *trigger = &trigdesc->triggers[tgindx[i]];
1454                 HeapTuple       newtuple;
1455
1456                 if (!trigger->tgenabled)
1457                         continue;
1458                 LocTriggerData.tg_trigger = trigger;
1459                 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1460                                                                            tgindx[i],
1461                                                                            relinfo->ri_TrigFunctions,
1462                                                                            relinfo->ri_TrigInstrument,
1463                                                                            GetPerTupleMemoryContext(estate));
1464
1465                 if (newtuple)
1466                         ereport(ERROR,
1467                                         (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1468                                   errmsg("BEFORE STATEMENT trigger cannot return a value")));
1469         }
1470 }
1471
1472 void
1473 ExecASDeleteTriggers(EState *estate, ResultRelInfo *relinfo)
1474 {
1475         TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1476
1477         if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_DELETE] > 0)
1478                 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_DELETE,
1479                                                           false, NULL, NULL);
1480 }
1481
1482 bool
1483 ExecBRDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
1484                                          ItemPointer tupleid,
1485                                          CommandId cid)
1486 {
1487         TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1488         int                     ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_DELETE];
1489         int                *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_DELETE];
1490         bool            result = true;
1491         TriggerData LocTriggerData;
1492         HeapTuple       trigtuple;
1493         HeapTuple       newtuple;
1494         TupleTableSlot *newSlot;
1495         int                     i;
1496
1497         trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, cid, &newSlot);
1498         if (trigtuple == NULL)
1499                 return false;
1500
1501         LocTriggerData.type = T_TriggerData;
1502         LocTriggerData.tg_event = TRIGGER_EVENT_DELETE |
1503                 TRIGGER_EVENT_ROW |
1504                 TRIGGER_EVENT_BEFORE;
1505         LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1506         LocTriggerData.tg_newtuple = NULL;
1507         LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1508         for (i = 0; i < ntrigs; i++)
1509         {
1510                 Trigger    *trigger = &trigdesc->triggers[tgindx[i]];
1511
1512                 if (!trigger->tgenabled)
1513                         continue;
1514                 LocTriggerData.tg_trigtuple = trigtuple;
1515                 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1516                 LocTriggerData.tg_trigger = trigger;
1517                 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1518                                                                            tgindx[i],
1519                                                                            relinfo->ri_TrigFunctions,
1520                                                                            relinfo->ri_TrigInstrument,
1521                                                                            GetPerTupleMemoryContext(estate));
1522                 if (newtuple == NULL)
1523                 {
1524                         result = false;         /* tell caller to suppress delete */
1525                         break;
1526                 }
1527                 if (newtuple != trigtuple)
1528                         heap_freetuple(newtuple);
1529         }
1530         heap_freetuple(trigtuple);
1531
1532         return result;
1533 }
1534
1535 void
1536 ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo,
1537                                          ItemPointer tupleid)
1538 {
1539         TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1540
1541         if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0)
1542         {
1543                 HeapTuple       trigtuple = GetTupleForTrigger(estate, relinfo,
1544                                                                                                    tupleid,
1545                                                                                                    (CommandId) 0,
1546                                                                                                    NULL);
1547
1548                 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_DELETE,
1549                                                           true, trigtuple, NULL);
1550                 heap_freetuple(trigtuple);
1551         }
1552 }
1553
1554 void
1555 ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
1556 {
1557         TriggerDesc *trigdesc;
1558         int                     ntrigs;
1559         int                *tgindx;
1560         int                     i;
1561         TriggerData LocTriggerData;
1562
1563         trigdesc = relinfo->ri_TrigDesc;
1564
1565         if (trigdesc == NULL)
1566                 return;
1567
1568         ntrigs = trigdesc->n_before_statement[TRIGGER_EVENT_UPDATE];
1569         tgindx = trigdesc->tg_before_statement[TRIGGER_EVENT_UPDATE];
1570
1571         if (ntrigs == 0)
1572                 return;
1573
1574         LocTriggerData.type = T_TriggerData;
1575         LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
1576                 TRIGGER_EVENT_BEFORE;
1577         LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1578         LocTriggerData.tg_trigtuple = NULL;
1579         LocTriggerData.tg_newtuple = NULL;
1580         LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1581         LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1582         for (i = 0; i < ntrigs; i++)
1583         {
1584                 Trigger    *trigger = &trigdesc->triggers[tgindx[i]];
1585                 HeapTuple       newtuple;
1586
1587                 if (!trigger->tgenabled)
1588                         continue;
1589                 LocTriggerData.tg_trigger = trigger;
1590                 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1591                                                                            tgindx[i],
1592                                                                            relinfo->ri_TrigFunctions,
1593                                                                            relinfo->ri_TrigInstrument,
1594                                                                            GetPerTupleMemoryContext(estate));
1595
1596                 if (newtuple)
1597                         ereport(ERROR,
1598                                         (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
1599                                   errmsg("BEFORE STATEMENT trigger cannot return a value")));
1600         }
1601 }
1602
1603 void
1604 ExecASUpdateTriggers(EState *estate, ResultRelInfo *relinfo)
1605 {
1606         TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1607
1608         if (trigdesc && trigdesc->n_after_statement[TRIGGER_EVENT_UPDATE] > 0)
1609                 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_UPDATE,
1610                                                           false, NULL, NULL);
1611 }
1612
1613 HeapTuple
1614 ExecBRUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
1615                                          ItemPointer tupleid, HeapTuple newtuple,
1616                                          CommandId cid)
1617 {
1618         TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1619         int                     ntrigs = trigdesc->n_before_row[TRIGGER_EVENT_UPDATE];
1620         int                *tgindx = trigdesc->tg_before_row[TRIGGER_EVENT_UPDATE];
1621         TriggerData LocTriggerData;
1622         HeapTuple       trigtuple;
1623         HeapTuple       oldtuple;
1624         HeapTuple       intuple = newtuple;
1625         TupleTableSlot *newSlot;
1626         int                     i;
1627
1628         trigtuple = GetTupleForTrigger(estate, relinfo, tupleid, cid, &newSlot);
1629         if (trigtuple == NULL)
1630                 return NULL;
1631
1632         /*
1633          * In READ COMMITTED isolation level it's possible that newtuple was
1634          * changed due to concurrent update.
1635          */
1636         if (newSlot != NULL)
1637                 intuple = newtuple = ExecRemoveJunk(estate->es_junkFilter, newSlot);
1638
1639         LocTriggerData.type = T_TriggerData;
1640         LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE |
1641                 TRIGGER_EVENT_ROW |
1642                 TRIGGER_EVENT_BEFORE;
1643         LocTriggerData.tg_relation = relinfo->ri_RelationDesc;
1644         for (i = 0; i < ntrigs; i++)
1645         {
1646                 Trigger    *trigger = &trigdesc->triggers[tgindx[i]];
1647
1648                 if (!trigger->tgenabled)
1649                         continue;
1650                 LocTriggerData.tg_trigtuple = trigtuple;
1651                 LocTriggerData.tg_newtuple = oldtuple = newtuple;
1652                 LocTriggerData.tg_trigtuplebuf = InvalidBuffer;
1653                 LocTriggerData.tg_newtuplebuf = InvalidBuffer;
1654                 LocTriggerData.tg_trigger = trigger;
1655                 newtuple = ExecCallTriggerFunc(&LocTriggerData,
1656                                                                            tgindx[i],
1657                                                                            relinfo->ri_TrigFunctions,
1658                                                                            relinfo->ri_TrigInstrument,
1659                                                                            GetPerTupleMemoryContext(estate));
1660                 if (oldtuple != newtuple && oldtuple != intuple)
1661                         heap_freetuple(oldtuple);
1662                 if (newtuple == NULL)
1663                         break;
1664         }
1665         heap_freetuple(trigtuple);
1666         return newtuple;
1667 }
1668
1669 void
1670 ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo,
1671                                          ItemPointer tupleid, HeapTuple newtuple)
1672 {
1673         TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
1674
1675         if (trigdesc && trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0)
1676         {
1677                 HeapTuple       trigtuple = GetTupleForTrigger(estate, relinfo,
1678                                                                                                    tupleid,
1679                                                                                                    (CommandId) 0,
1680                                                                                                    NULL);
1681
1682                 AfterTriggerSaveEvent(relinfo, TRIGGER_EVENT_UPDATE,
1683                                                           true, trigtuple, newtuple);
1684                 heap_freetuple(trigtuple);
1685         }
1686 }
1687
1688
1689 static HeapTuple
1690 GetTupleForTrigger(EState *estate, ResultRelInfo *relinfo,
1691                                    ItemPointer tid, CommandId cid,
1692                                    TupleTableSlot **newSlot)
1693 {
1694         Relation        relation = relinfo->ri_RelationDesc;
1695         HeapTupleData tuple;
1696         HeapTuple       result;
1697         Buffer          buffer;
1698
1699         if (newSlot != NULL)
1700         {
1701                 HTSU_Result test;
1702                 ItemPointerData update_ctid;
1703                 TransactionId update_xmax;
1704
1705                 *newSlot = NULL;
1706
1707                 /*
1708                  * lock tuple for update
1709                  */
1710 ltrmark:;
1711                 tuple.t_self = *tid;
1712                 test = heap_lock_tuple(relation, &tuple, &buffer,
1713                                                            &update_ctid, &update_xmax, cid,
1714                                                            LockTupleExclusive, false);
1715                 switch (test)
1716                 {
1717                         case HeapTupleSelfUpdated:
1718                                 /* treat it as deleted; do not process */
1719                                 ReleaseBuffer(buffer);
1720                                 return NULL;
1721
1722                         case HeapTupleMayBeUpdated:
1723                                 break;
1724
1725                         case HeapTupleUpdated:
1726                                 ReleaseBuffer(buffer);
1727                                 if (IsXactIsoLevelSerializable)
1728                                         ereport(ERROR,
1729                                                         (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
1730                                                          errmsg("could not serialize access due to concurrent update")));
1731                                 else if (!ItemPointerEquals(&update_ctid, &tuple.t_self))
1732                                 {
1733                                         /* it was updated, so look at the updated version */
1734                                         TupleTableSlot *epqslot;
1735
1736                                         epqslot = EvalPlanQual(estate,
1737                                                                                    relinfo->ri_RangeTableIndex,
1738                                                                                    &update_ctid,
1739                                                                                    update_xmax,
1740                                                                                    cid);
1741                                         if (!TupIsNull(epqslot))
1742                                         {
1743                                                 *tid = update_ctid;
1744                                                 *newSlot = epqslot;
1745                                                 goto ltrmark;
1746                                         }
1747                                 }
1748
1749                                 /*
1750                                  * if tuple was deleted or PlanQual failed for updated tuple -
1751                                  * we have not process this tuple!
1752                                  */
1753                                 return NULL;
1754
1755                         default:
1756                                 ReleaseBuffer(buffer);
1757                                 elog(ERROR, "unrecognized heap_lock_tuple status: %u", test);
1758                                 return NULL;    /* keep compiler quiet */
1759                 }
1760         }
1761         else
1762         {
1763                 PageHeader      dp;
1764                 ItemId          lp;
1765
1766                 buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
1767
1768                 dp = (PageHeader) BufferGetPage(buffer);
1769                 lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
1770
1771                 Assert(ItemIdIsUsed(lp));
1772
1773                 tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
1774                 tuple.t_len = ItemIdGetLength(lp);
1775                 tuple.t_self = *tid;
1776                 tuple.t_tableOid = RelationGetRelid(relation);
1777         }
1778
1779         result = heap_copytuple(&tuple);
1780         ReleaseBuffer(buffer);
1781
1782         return result;
1783 }
1784
1785
1786 /* ----------
1787  * After-trigger stuff
1788  *
1789  * The AfterTriggersData struct holds data about pending AFTER trigger events
1790  * during the current transaction tree.  (BEFORE triggers are fired
1791  * immediately so we don't need any persistent state about them.)  The struct
1792  * and most of its subsidiary data are kept in TopTransactionContext; however
1793  * the individual event records are kept in CurTransactionContext, so that
1794  * they will easily go away during subtransaction abort.
1795  *
1796  * Because the list of pending events can grow large, we go to some effort
1797  * to minimize memory consumption.      We do not use the generic List mechanism
1798  * but thread the events manually.
1799  *
1800  * XXX We need to be able to save the per-event data in a file if it grows too
1801  * large.
1802  * ----------
1803  */
1804
1805 /* Per-trigger SET CONSTRAINT status */
1806 typedef struct SetConstraintTriggerData
1807 {
1808         Oid                     sct_tgoid;
1809         bool            sct_tgisdeferred;
1810 } SetConstraintTriggerData;
1811
1812 typedef struct SetConstraintTriggerData *SetConstraintTrigger;
1813
1814 /*
1815  * SET CONSTRAINT intra-transaction status.
1816  *
1817  * We make this a single palloc'd object so it can be copied and freed easily.
1818  *
1819  * all_isset and all_isdeferred are used to keep track
1820  * of SET CONSTRAINTS ALL {DEFERRED, IMMEDIATE}.
1821  *
1822  * trigstates[] stores per-trigger tgisdeferred settings.
1823  */
1824 typedef struct SetConstraintStateData
1825 {
1826         bool            all_isset;
1827         bool            all_isdeferred;
1828         int                     numstates;              /* number of trigstates[] entries in use */
1829         int                     numalloc;               /* allocated size of trigstates[] */
1830         SetConstraintTriggerData trigstates[1];         /* VARIABLE LENGTH ARRAY */
1831 } SetConstraintStateData;
1832
1833 typedef SetConstraintStateData *SetConstraintState;
1834
1835
1836 /*
1837  * Per-trigger-event data
1838  *
1839  * Note: ate_firing_id is meaningful when either AFTER_TRIGGER_DONE
1840  * or AFTER_TRIGGER_IN_PROGRESS is set.  It indicates which trigger firing
1841  * cycle the trigger was or will be fired in.
1842  */
1843 typedef struct AfterTriggerEventData *AfterTriggerEvent;
1844
1845 typedef struct AfterTriggerEventData
1846 {
1847         AfterTriggerEvent ate_next; /* list link */
1848         TriggerEvent ate_event;         /* event type and status bits */
1849         CommandId       ate_firing_id;  /* ID for firing cycle */
1850         Oid                     ate_tgoid;              /* the trigger's ID */
1851         Oid                     ate_relid;              /* the relation it's on */
1852         ItemPointerData ate_oldctid;    /* specific tuple(s) involved */
1853         ItemPointerData ate_newctid;
1854 } AfterTriggerEventData;
1855
1856 /* A list of events */
1857 typedef struct AfterTriggerEventList
1858 {
1859         AfterTriggerEvent head;
1860         AfterTriggerEvent tail;
1861 } AfterTriggerEventList;
1862
1863
1864 /*
1865  * All per-transaction data for the AFTER TRIGGERS module.
1866  *
1867  * AfterTriggersData has the following fields:
1868  *
1869  * firing_counter is incremented for each call of afterTriggerInvokeEvents.
1870  * We mark firable events with the current firing cycle's ID so that we can
1871  * tell which ones to work on.  This ensures sane behavior if a trigger
1872  * function chooses to do SET CONSTRAINTS: the inner SET CONSTRAINTS will
1873  * only fire those events that weren't already scheduled for firing.
1874  *
1875  * state keeps track of the transaction-local effects of SET CONSTRAINTS.
1876  * This is saved and restored across failed subtransactions.
1877  *
1878  * events is the current list of deferred events.  This is global across
1879  * all subtransactions of the current transaction.      In a subtransaction
1880  * abort, we know that the events added by the subtransaction are at the
1881  * end of the list, so it is relatively easy to discard them.
1882  *
1883  * query_depth is the current depth of nested AfterTriggerBeginQuery calls
1884  * (-1 when the stack is empty).
1885  *
1886  * query_stack[query_depth] is a list of AFTER trigger events queued by the
1887  * current query (and the query_stack entries below it are lists of trigger
1888  * events queued by calling queries).  None of these are valid until the
1889  * matching AfterTriggerEndQuery call occurs.  At that point we fire
1890  * immediate-mode triggers, and append any deferred events to the main events
1891  * list.
1892  *
1893  * maxquerydepth is just the allocated length of query_stack.
1894  *
1895  * state_stack is a stack of pointers to saved copies of the SET CONSTRAINTS
1896  * state data; each subtransaction level that modifies that state first
1897  * saves a copy, which we use to restore the state if we abort.
1898  *
1899  * events_stack is a stack of copies of the events head/tail pointers,
1900  * which we use to restore those values during subtransaction abort.
1901  *
1902  * depth_stack is a stack of copies of subtransaction-start-time query_depth,
1903  * which we similarly use to clean up at subtransaction abort.
1904  *
1905  * firing_stack is a stack of copies of subtransaction-start-time
1906  * firing_counter.      We use this to recognize which deferred triggers were
1907  * fired (or marked for firing) within an aborted subtransaction.
1908  *
1909  * We use GetCurrentTransactionNestLevel() to determine the correct array
1910  * index in these stacks.  maxtransdepth is the number of allocated entries in
1911  * each stack.  (By not keeping our own stack pointer, we can avoid trouble
1912  * in cases where errors during subxact abort cause multiple invocations
1913  * of AfterTriggerEndSubXact() at the same nesting depth.)
1914  */
1915 typedef struct AfterTriggersData
1916 {
1917         CommandId       firing_counter; /* next firing ID to assign */
1918         SetConstraintState state;       /* the active S C state */
1919         AfterTriggerEventList events;           /* deferred-event list */
1920         int                     query_depth;    /* current query list index */
1921         AfterTriggerEventList *query_stack; /* events pending from each query */
1922         int                     maxquerydepth;  /* allocated len of above array */
1923
1924         /* these fields are just for resetting at subtrans abort: */
1925
1926         SetConstraintState *state_stack;        /* stacked S C states */
1927         AfterTriggerEventList *events_stack;            /* stacked list pointers */
1928         int                *depth_stack;        /* stacked query_depths */
1929         CommandId  *firing_stack;       /* stacked firing_counters */
1930         int                     maxtransdepth;  /* allocated len of above arrays */
1931 } AfterTriggersData;
1932
1933 typedef AfterTriggersData *AfterTriggers;
1934
1935 static AfterTriggers afterTriggers;
1936
1937
1938 static void AfterTriggerExecute(AfterTriggerEvent event,
1939                                         Relation rel, TriggerDesc *trigdesc,
1940                                         FmgrInfo *finfo,
1941                                         Instrumentation *instr,
1942                                         MemoryContext per_tuple_context);
1943 static SetConstraintState SetConstraintStateCreate(int numalloc);
1944 static SetConstraintState SetConstraintStateCopy(SetConstraintState state);
1945 static SetConstraintState SetConstraintStateAddItem(SetConstraintState state,
1946                                                   Oid tgoid, bool tgisdeferred);
1947
1948
1949 /* ----------
1950  * afterTriggerCheckState()
1951  *
1952  *      Returns true if the trigger identified by tgoid is actually
1953  *      in state DEFERRED.
1954  * ----------
1955  */
1956 static bool
1957 afterTriggerCheckState(Oid tgoid, TriggerEvent eventstate)
1958 {
1959         SetConstraintState state = afterTriggers->state;
1960         int                     i;
1961
1962         /*
1963          * For not-deferrable triggers (i.e. normal AFTER ROW triggers and
1964          * constraints declared NOT DEFERRABLE), the state is always false.
1965          */
1966         if ((eventstate & AFTER_TRIGGER_DEFERRABLE) == 0)
1967                 return false;
1968
1969         /*
1970          * Check if SET CONSTRAINTS has been executed for this specific trigger.
1971          */
1972         for (i = 0; i < state->numstates; i++)
1973         {
1974                 if (state->trigstates[i].sct_tgoid == tgoid)
1975                         return state->trigstates[i].sct_tgisdeferred;
1976         }
1977
1978         /*
1979          * Check if SET CONSTRAINTS ALL has been executed; if so use that.
1980          */
1981         if (state->all_isset)
1982                 return state->all_isdeferred;
1983
1984         /*
1985          * Otherwise return the default state for the trigger.
1986          */
1987         return ((eventstate & AFTER_TRIGGER_INITDEFERRED) != 0);
1988 }
1989
1990
1991 /* ----------
1992  * afterTriggerAddEvent()
1993  *
1994  *      Add a new trigger event to the current query's queue.
1995  * ----------
1996  */
1997 static void
1998 afterTriggerAddEvent(AfterTriggerEvent event)
1999 {
2000         AfterTriggerEventList *events;
2001
2002         Assert(event->ate_next == NULL);
2003
2004         /* Must be inside a query */
2005         Assert(afterTriggers->query_depth >= 0);
2006
2007         events = &afterTriggers->query_stack[afterTriggers->query_depth];
2008         if (events->tail == NULL)
2009         {
2010                 /* first list entry */
2011                 events->head = event;
2012                 events->tail = event;
2013         }
2014         else
2015         {
2016                 events->tail->ate_next = event;
2017                 events->tail = event;
2018         }
2019 }
2020
2021
2022 /* ----------
2023  * AfterTriggerExecute()
2024  *
2025  *      Fetch the required tuples back from the heap and fire one
2026  *      single trigger function.
2027  *
2028  *      Frequently, this will be fired many times in a row for triggers of
2029  *      a single relation.      Therefore, we cache the open relation and provide
2030  *      fmgr lookup cache space at the caller level.  (For triggers fired at
2031  *      the end of a query, we can even piggyback on the executor's state.)
2032  *
2033  *      event: event currently being fired.
2034  *      rel: open relation for event.
2035  *      trigdesc: working copy of rel's trigger info.
2036  *      finfo: array of fmgr lookup cache entries (one per trigger in trigdesc).
2037  *      instr: array of EXPLAIN ANALYZE instrumentation nodes (one per trigger),
2038  *              or NULL if no instrumentation is wanted.
2039  *      per_tuple_context: memory context to call trigger function in.
2040  * ----------
2041  */
2042 static void
2043 AfterTriggerExecute(AfterTriggerEvent event,
2044                                         Relation rel, TriggerDesc *trigdesc,
2045                                         FmgrInfo *finfo, Instrumentation *instr,
2046                                         MemoryContext per_tuple_context)
2047 {
2048         Oid                     tgoid = event->ate_tgoid;
2049         TriggerData LocTriggerData;
2050         HeapTupleData oldtuple;
2051         HeapTupleData newtuple;
2052         HeapTuple       rettuple;
2053         Buffer          oldbuffer = InvalidBuffer;
2054         Buffer          newbuffer = InvalidBuffer;
2055         int                     tgindx;
2056
2057         /*
2058          * Locate trigger in trigdesc.
2059          */
2060         LocTriggerData.tg_trigger = NULL;
2061         for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++)
2062         {
2063                 if (trigdesc->triggers[tgindx].tgoid == tgoid)
2064                 {
2065                         LocTriggerData.tg_trigger = &(trigdesc->triggers[tgindx]);
2066                         break;
2067                 }
2068         }
2069         if (LocTriggerData.tg_trigger == NULL)
2070                 elog(ERROR, "could not find trigger %u", tgoid);
2071
2072         /*
2073          * If doing EXPLAIN ANALYZE, start charging time to this trigger. We want
2074          * to include time spent re-fetching tuples in the trigger cost.
2075          */
2076         if (instr)
2077                 InstrStartNode(instr + tgindx);
2078
2079         /*
2080          * Fetch the required OLD and NEW tuples.
2081          */
2082         if (ItemPointerIsValid(&(event->ate_oldctid)))
2083         {
2084                 ItemPointerCopy(&(event->ate_oldctid), &(oldtuple.t_self));
2085                 if (!heap_fetch(rel, SnapshotAny, &oldtuple, &oldbuffer, false, NULL))
2086                         elog(ERROR, "failed to fetch old tuple for AFTER trigger");
2087         }
2088
2089         if (ItemPointerIsValid(&(event->ate_newctid)))
2090         {
2091                 ItemPointerCopy(&(event->ate_newctid), &(newtuple.t_self));
2092                 if (!heap_fetch(rel, SnapshotAny, &newtuple, &newbuffer, false, NULL))
2093                         elog(ERROR, "failed to fetch new tuple for AFTER trigger");
2094         }
2095
2096         /*
2097          * Setup the trigger information
2098          */
2099         LocTriggerData.type = T_TriggerData;
2100         LocTriggerData.tg_event =
2101                 event->ate_event & (TRIGGER_EVENT_OPMASK | TRIGGER_EVENT_ROW);
2102         LocTriggerData.tg_relation = rel;
2103
2104         switch (event->ate_event & TRIGGER_EVENT_OPMASK)
2105         {
2106                 case TRIGGER_EVENT_INSERT:
2107                         LocTriggerData.tg_trigtuple = &newtuple;
2108                         LocTriggerData.tg_newtuple = NULL;
2109                         LocTriggerData.tg_trigtuplebuf = newbuffer;
2110                         LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2111                         break;
2112
2113                 case TRIGGER_EVENT_UPDATE:
2114                         LocTriggerData.tg_trigtuple = &oldtuple;
2115                         LocTriggerData.tg_newtuple = &newtuple;
2116                         LocTriggerData.tg_trigtuplebuf = oldbuffer;
2117                         LocTriggerData.tg_newtuplebuf = newbuffer;
2118                         break;
2119
2120                 case TRIGGER_EVENT_DELETE:
2121                         LocTriggerData.tg_trigtuple = &oldtuple;
2122                         LocTriggerData.tg_newtuple = NULL;
2123                         LocTriggerData.tg_trigtuplebuf = oldbuffer;
2124                         LocTriggerData.tg_newtuplebuf = InvalidBuffer;
2125                         break;
2126         }
2127
2128         MemoryContextReset(per_tuple_context);
2129
2130         /*
2131          * Call the trigger and throw away any possibly returned updated tuple.
2132          * (Don't let ExecCallTriggerFunc measure EXPLAIN time.)
2133          */
2134         rettuple = ExecCallTriggerFunc(&LocTriggerData,
2135                                                                    tgindx,
2136                                                                    finfo,
2137                                                                    NULL,
2138                                                                    per_tuple_context);
2139         if (rettuple != NULL && rettuple != &oldtuple && rettuple != &newtuple)
2140                 heap_freetuple(rettuple);
2141
2142         /*
2143          * Release buffers
2144          */
2145         if (oldbuffer != InvalidBuffer)
2146                 ReleaseBuffer(oldbuffer);
2147         if (newbuffer != InvalidBuffer)
2148                 ReleaseBuffer(newbuffer);
2149
2150         /*
2151          * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count
2152          * one "tuple returned" (really the number of firings).
2153          */
2154         if (instr)
2155                 InstrStopNode(instr + tgindx, true);
2156 }
2157
2158
2159 /*
2160  * afterTriggerMarkEvents()
2161  *
2162  *      Scan the given event list for not yet invoked events.  Mark the ones
2163  *      that can be invoked now with the current firing ID.
2164  *
2165  *      If move_list isn't NULL, events that are not to be invoked now are
2166  *      removed from the given list and appended to move_list.
2167  *
2168  *      When immediate_only is TRUE, do not invoke currently-deferred triggers.
2169  *      (This will be FALSE only at main transaction exit.)
2170  *
2171  *      Returns TRUE if any invokable events were found.
2172  */
2173 static bool
2174 afterTriggerMarkEvents(AfterTriggerEventList *events,
2175                                            AfterTriggerEventList *move_list,
2176                                            bool immediate_only)
2177 {
2178         bool            found = false;
2179         AfterTriggerEvent event,
2180                                 prev_event;
2181
2182         prev_event = NULL;
2183         event = events->head;
2184
2185         while (event != NULL)
2186         {
2187                 bool            defer_it = false;
2188                 AfterTriggerEvent next_event;
2189
2190                 if (!(event->ate_event &
2191                           (AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS)))
2192                 {
2193                         /*
2194                          * This trigger hasn't been called or scheduled yet. Check if we
2195                          * should call it now.
2196                          */
2197                         if (immediate_only &&
2198                                 afterTriggerCheckState(event->ate_tgoid, event->ate_event))
2199                         {
2200                                 defer_it = true;
2201                         }
2202                         else
2203                         {
2204                                 /*
2205                                  * Mark it as to be fired in this firing cycle.
2206                                  */
2207                                 event->ate_firing_id = afterTriggers->firing_counter;
2208                                 event->ate_event |= AFTER_TRIGGER_IN_PROGRESS;
2209                                 found = true;
2210                         }
2211                 }
2212
2213                 /*
2214                  * If it's deferred, move it to move_list, if requested.
2215                  */
2216                 next_event = event->ate_next;
2217
2218                 if (defer_it && move_list != NULL)
2219                 {
2220                         /* Delink it from input list */
2221                         if (prev_event)
2222                                 prev_event->ate_next = next_event;
2223                         else
2224                                 events->head = next_event;
2225                         /* and add it to move_list */
2226                         event->ate_next = NULL;
2227                         if (move_list->tail == NULL)
2228                         {
2229                                 /* first list entry */
2230                                 move_list->head = event;
2231                                 move_list->tail = event;
2232                         }
2233                         else
2234                         {
2235                                 move_list->tail->ate_next = event;
2236                                 move_list->tail = event;
2237                         }
2238                 }
2239                 else
2240                 {
2241                         /* Keep it in input list */
2242                         prev_event = event;
2243                 }
2244
2245                 event = next_event;
2246         }
2247
2248         /* Update list tail pointer in case we moved tail event */
2249         events->tail = prev_event;
2250
2251         return found;
2252 }
2253
2254 /* ----------
2255  * afterTriggerInvokeEvents()
2256  *
2257  *      Scan the given event list for events that are marked as to be fired
2258  *      in the current firing cycle, and fire them.
2259  *
2260  *      If estate isn't NULL, then we expect that all the firable events are
2261  *      for triggers of the relations included in the estate's result relation
2262  *      array.  This allows us to re-use the estate's open relations and
2263  *      trigger cache info.  When estate is NULL, we have to find the relations
2264  *      the hard way.
2265  *
2266  *      When delete_ok is TRUE, it's okay to delete fully-processed events.
2267  *      The events list pointers are updated.
2268  * ----------
2269  */
2270 static void
2271 afterTriggerInvokeEvents(AfterTriggerEventList *events,
2272                                                  CommandId firing_id,
2273                                                  EState *estate,
2274                                                  bool delete_ok)
2275 {
2276         AfterTriggerEvent event,
2277                                 prev_event;
2278         MemoryContext per_tuple_context;
2279         Relation        rel = NULL;
2280         TriggerDesc *trigdesc = NULL;
2281         FmgrInfo   *finfo = NULL;
2282         Instrumentation *instr = NULL;
2283
2284         /* Make a per-tuple memory context for trigger function calls */
2285         per_tuple_context =
2286                 AllocSetContextCreate(CurrentMemoryContext,
2287                                                           "AfterTriggerTupleContext",
2288                                                           ALLOCSET_DEFAULT_MINSIZE,
2289                                                           ALLOCSET_DEFAULT_INITSIZE,
2290                                                           ALLOCSET_DEFAULT_MAXSIZE);
2291
2292         prev_event = NULL;
2293         event = events->head;
2294
2295         while (event != NULL)
2296         {
2297                 AfterTriggerEvent next_event;
2298
2299                 /*
2300                  * Is it one for me to fire?
2301                  */
2302                 if ((event->ate_event & AFTER_TRIGGER_IN_PROGRESS) &&
2303                         event->ate_firing_id == firing_id)
2304                 {
2305                         /*
2306                          * So let's fire it... but first, open the correct relation if
2307                          * this is not the same relation as before.
2308                          */
2309                         if (rel == NULL || rel->rd_id != event->ate_relid)
2310                         {
2311                                 if (estate)
2312                                 {
2313                                         /* Find target relation among estate's result rels */
2314                                         ResultRelInfo *rInfo;
2315                                         int                     nr;
2316
2317                                         rInfo = estate->es_result_relations;
2318                                         nr = estate->es_num_result_relations;
2319                                         while (nr > 0)
2320                                         {
2321                                                 if (rInfo->ri_RelationDesc->rd_id == event->ate_relid)
2322                                                         break;
2323                                                 rInfo++;
2324                                                 nr--;
2325                                         }
2326                                         if (nr <= 0)    /* should not happen */
2327                                                 elog(ERROR, "could not find relation %u among query result relations",
2328                                                          event->ate_relid);
2329                                         rel = rInfo->ri_RelationDesc;
2330                                         trigdesc = rInfo->ri_TrigDesc;
2331                                         finfo = rInfo->ri_TrigFunctions;
2332                                         instr = rInfo->ri_TrigInstrument;
2333                                 }
2334                                 else
2335                                 {
2336                                         /* Hard way: we manage the resources for ourselves */
2337                                         if (rel)
2338                                                 heap_close(rel, NoLock);
2339                                         if (trigdesc)
2340                                                 FreeTriggerDesc(trigdesc);
2341                                         if (finfo)
2342                                                 pfree(finfo);
2343                                         Assert(instr == NULL);          /* never used in this case */
2344
2345                                         /*
2346                                          * We assume that an appropriate lock is still held by the
2347                                          * executor, so grab no new lock here.
2348                                          */
2349                                         rel = heap_open(event->ate_relid, NoLock);
2350
2351                                         /*
2352                                          * Copy relation's trigger info so that we have a stable
2353                                          * copy no matter what the called triggers do.
2354                                          */
2355                                         trigdesc = CopyTriggerDesc(rel->trigdesc);
2356
2357                                         if (trigdesc == NULL)           /* should not happen */
2358                                                 elog(ERROR, "relation %u has no triggers",
2359                                                          event->ate_relid);
2360
2361                                         /*
2362                                          * Allocate space to cache fmgr lookup info for triggers.
2363                                          */
2364                                         finfo = (FmgrInfo *)
2365                                                 palloc0(trigdesc->numtriggers * sizeof(FmgrInfo));
2366
2367                                         /* Never any EXPLAIN info in this case */
2368                                 }
2369                         }
2370
2371                         /*
2372                          * Fire it.  Note that the AFTER_TRIGGER_IN_PROGRESS flag is still
2373                          * set, so recursive examinations of the event list won't try to
2374                          * re-fire it.
2375                          */
2376                         AfterTriggerExecute(event, rel, trigdesc, finfo, instr,
2377                                                                 per_tuple_context);
2378
2379                         /*
2380                          * Mark the event as done.
2381                          */
2382                         event->ate_event &= ~AFTER_TRIGGER_IN_PROGRESS;
2383                         event->ate_event |= AFTER_TRIGGER_DONE;
2384                 }
2385
2386                 /*
2387                  * If it's now done, throw it away, if allowed.
2388                  *
2389                  * NB: it's possible the trigger call above added more events to the
2390                  * queue, or that calls we will do later will want to add more, so we
2391                  * have to be careful about maintaining list validity at all points
2392                  * here.
2393                  */
2394                 next_event = event->ate_next;
2395
2396                 if ((event->ate_event & AFTER_TRIGGER_DONE) && delete_ok)
2397                 {
2398                         /* Delink it from list and free it */
2399                         if (prev_event)
2400                                 prev_event->ate_next = next_event;
2401                         else
2402                                 events->head = next_event;
2403                         pfree(event);
2404                 }
2405                 else
2406                 {
2407                         /* Keep it in list */
2408                         prev_event = event;
2409                 }
2410
2411                 event = next_event;
2412         }
2413
2414         /* Update list tail pointer in case we just deleted tail event */
2415         events->tail = prev_event;
2416
2417         /* Release working resources */
2418         if (!estate)
2419         {
2420                 if (rel)
2421                         heap_close(rel, NoLock);
2422                 if (trigdesc)
2423                         FreeTriggerDesc(trigdesc);
2424                 if (finfo)
2425                         pfree(finfo);
2426                 Assert(instr == NULL);  /* never used in this case */
2427         }
2428         MemoryContextDelete(per_tuple_context);
2429 }
2430
2431
2432 /* ----------
2433  * AfterTriggerBeginXact()
2434  *
2435  *      Called at transaction start (either BEGIN or implicit for single
2436  *      statement outside of transaction block).
2437  * ----------
2438  */
2439 void
2440 AfterTriggerBeginXact(void)
2441 {
2442         Assert(afterTriggers == NULL);
2443
2444         /*
2445          * Build empty after-trigger state structure
2446          */
2447         afterTriggers = (AfterTriggers)
2448                 MemoryContextAlloc(TopTransactionContext,
2449                                                    sizeof(AfterTriggersData));
2450
2451         afterTriggers->firing_counter = FirstCommandId;
2452         afterTriggers->state = SetConstraintStateCreate(8);
2453         afterTriggers->events.head = NULL;
2454         afterTriggers->events.tail = NULL;
2455         afterTriggers->query_depth = -1;
2456
2457         /* We initialize the query stack to a reasonable size */
2458         afterTriggers->query_stack = (AfterTriggerEventList *)
2459                 MemoryContextAlloc(TopTransactionContext,
2460                                                    8 * sizeof(AfterTriggerEventList));
2461         afterTriggers->maxquerydepth = 8;
2462
2463         /* Subtransaction stack is empty until/unless needed */
2464         afterTriggers->state_stack = NULL;
2465         afterTriggers->events_stack = NULL;
2466         afterTriggers->depth_stack = NULL;
2467         afterTriggers->firing_stack = NULL;
2468         afterTriggers->maxtransdepth = 0;
2469 }
2470
2471
2472 /* ----------
2473  * AfterTriggerBeginQuery()
2474  *
2475  *      Called just before we start processing a single query within a
2476  *      transaction (or subtransaction).  Set up to record AFTER trigger
2477  *      events queued by the query.  Note that it is allowed to have
2478  *      nested queries within a (sub)transaction.
2479  * ----------
2480  */
2481 void
2482 AfterTriggerBeginQuery(void)
2483 {
2484         /* Must be inside a transaction */
2485         Assert(afterTriggers != NULL);
2486
2487         /* Increase the query stack depth */
2488         afterTriggers->query_depth++;
2489
2490         /*
2491          * Allocate more space in the query stack if needed.
2492          */
2493         if (afterTriggers->query_depth >= afterTriggers->maxquerydepth)
2494         {
2495                 /* repalloc will keep the stack in the same context */
2496                 int                     new_alloc = afterTriggers->maxquerydepth * 2;
2497
2498                 afterTriggers->query_stack = (AfterTriggerEventList *)
2499                         repalloc(afterTriggers->query_stack,
2500                                          new_alloc * sizeof(AfterTriggerEventList));
2501                 afterTriggers->maxquerydepth = new_alloc;
2502         }
2503
2504         /* Initialize this query's list to empty */
2505         afterTriggers->query_stack[afterTriggers->query_depth].head = NULL;
2506         afterTriggers->query_stack[afterTriggers->query_depth].tail = NULL;
2507 }
2508
2509
2510 /* ----------
2511  * AfterTriggerEndQuery()
2512  *
2513  *      Called after one query has been completely processed. At this time
2514  *      we invoke all AFTER IMMEDIATE trigger events queued by the query, and
2515  *      transfer deferred trigger events to the global deferred-trigger list.
2516  *
2517  *      Note that this should be called just BEFORE closing down the executor
2518  *      with ExecutorEnd, because we make use of the EState's info about
2519  *      target relations.
2520  * ----------
2521  */
2522 void
2523 AfterTriggerEndQuery(EState *estate)
2524 {
2525         AfterTriggerEventList *events;
2526
2527         /* Must be inside a transaction */
2528         Assert(afterTriggers != NULL);
2529
2530         /* Must be inside a query, too */
2531         Assert(afterTriggers->query_depth >= 0);
2532
2533         /*
2534          * Process all immediate-mode triggers queued by the query, and move the
2535          * deferred ones to the main list of deferred events.
2536          *
2537          * Notice that we decide which ones will be fired, and put the deferred
2538          * ones on the main list, before anything is actually fired.  This ensures
2539          * reasonably sane behavior if a trigger function does SET CONSTRAINTS ...
2540          * IMMEDIATE: all events we have decided to defer will be available for it
2541          * to fire.
2542          *
2543          * If we find no firable events, we don't have to increment
2544          * firing_counter.
2545          */
2546         events = &afterTriggers->query_stack[afterTriggers->query_depth];
2547         if (afterTriggerMarkEvents(events, &afterTriggers->events, true))
2548         {
2549                 CommandId       firing_id = afterTriggers->firing_counter++;
2550
2551                 /* OK to delete the immediate events after processing them */
2552                 afterTriggerInvokeEvents(events, firing_id, estate, true);
2553         }
2554
2555         afterTriggers->query_depth--;
2556 }
2557
2558
2559 /* ----------
2560  * AfterTriggerFireDeferred()
2561  *
2562  *      Called just before the current transaction is committed. At this
2563  *      time we invoke all pending DEFERRED triggers.
2564  *
2565  *      It is possible for other modules to queue additional deferred triggers
2566  *      during pre-commit processing; therefore xact.c may have to call this
2567  *      multiple times.
2568  * ----------
2569  */
2570 void
2571 AfterTriggerFireDeferred(void)
2572 {
2573         AfterTriggerEventList *events;
2574
2575         /* Must be inside a transaction */
2576         Assert(afterTriggers != NULL);
2577
2578         /* ... but not inside a query */
2579         Assert(afterTriggers->query_depth == -1);
2580
2581         /*
2582          * If there are any triggers to fire, make sure we have set a snapshot for
2583          * them to use.  (Since PortalRunUtility doesn't set a snap for COMMIT, we
2584          * can't assume ActiveSnapshot is valid on entry.)
2585          */
2586         events = &afterTriggers->events;
2587         if (events->head != NULL)
2588                 ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
2589
2590         /*
2591          * Run all the remaining triggers.      Loop until they are all gone, just in
2592          * case some trigger queues more for us to do.
2593          */
2594         while (afterTriggerMarkEvents(events, NULL, false))
2595         {
2596                 CommandId       firing_id = afterTriggers->firing_counter++;
2597
2598                 afterTriggerInvokeEvents(events, firing_id, NULL, true);
2599         }
2600
2601         Assert(events->head == NULL);
2602 }
2603
2604
2605 /* ----------
2606  * AfterTriggerEndXact()
2607  *
2608  *      The current transaction is finishing.
2609  *
2610  *      Any unfired triggers are canceled so we simply throw
2611  *      away anything we know.
2612  *
2613  *      Note: it is possible for this to be called repeatedly in case of
2614  *      error during transaction abort; therefore, do not complain if
2615  *      already closed down.
2616  * ----------
2617  */
2618 void
2619 AfterTriggerEndXact(bool isCommit)
2620 {
2621         /*
2622          * Forget everything we know about AFTER triggers.
2623          *
2624          * Since all the info is in TopTransactionContext or children thereof, we
2625          * need do nothing special to reclaim memory.
2626          */
2627         afterTriggers = NULL;
2628 }
2629
2630 /*
2631  * AfterTriggerBeginSubXact()
2632  *
2633  *      Start a subtransaction.
2634  */
2635 void
2636 AfterTriggerBeginSubXact(void)
2637 {
2638         int                     my_level = GetCurrentTransactionNestLevel();
2639
2640         /*
2641          * Ignore call if the transaction is in aborted state.  (Probably
2642          * shouldn't happen?)
2643          */
2644         if (afterTriggers == NULL)
2645                 return;
2646
2647         /*
2648          * Allocate more space in the stacks if needed.
2649          */
2650         while (my_level >= afterTriggers->maxtransdepth)
2651         {
2652                 if (afterTriggers->maxtransdepth == 0)
2653                 {
2654                         MemoryContext old_cxt;
2655
2656                         old_cxt = MemoryContextSwitchTo(TopTransactionContext);
2657
2658 #define DEFTRIG_INITALLOC 8
2659                         afterTriggers->state_stack = (SetConstraintState *)
2660                                 palloc(DEFTRIG_INITALLOC * sizeof(SetConstraintState));
2661                         afterTriggers->events_stack = (AfterTriggerEventList *)
2662                                 palloc(DEFTRIG_INITALLOC * sizeof(AfterTriggerEventList));
2663                         afterTriggers->depth_stack = (int *)
2664                                 palloc(DEFTRIG_INITALLOC * sizeof(int));
2665                         afterTriggers->firing_stack = (CommandId *)
2666                                 palloc(DEFTRIG_INITALLOC * sizeof(CommandId));
2667                         afterTriggers->maxtransdepth = DEFTRIG_INITALLOC;
2668
2669                         MemoryContextSwitchTo(old_cxt);
2670                 }
2671                 else
2672                 {
2673                         /* repalloc will keep the stacks in the same context */
2674                         int                     new_alloc = afterTriggers->maxtransdepth * 2;
2675
2676                         afterTriggers->state_stack = (SetConstraintState *)
2677                                 repalloc(afterTriggers->state_stack,
2678                                                  new_alloc * sizeof(SetConstraintState));
2679                         afterTriggers->events_stack = (AfterTriggerEventList *)
2680                                 repalloc(afterTriggers->events_stack,
2681                                                  new_alloc * sizeof(AfterTriggerEventList));
2682                         afterTriggers->depth_stack = (int *)
2683                                 repalloc(afterTriggers->depth_stack,
2684                                                  new_alloc * sizeof(int));
2685                         afterTriggers->firing_stack = (CommandId *)
2686                                 repalloc(afterTriggers->firing_stack,
2687                                                  new_alloc * sizeof(CommandId));
2688                         afterTriggers->maxtransdepth = new_alloc;
2689                 }
2690         }
2691
2692         /*
2693          * Push the current information into the stack.  The SET CONSTRAINTS state
2694          * is not saved until/unless changed.
2695          */
2696         afterTriggers->state_stack[my_level] = NULL;
2697         afterTriggers->events_stack[my_level] = afterTriggers->events;
2698         afterTriggers->depth_stack[my_level] = afterTriggers->query_depth;
2699         afterTriggers->firing_stack[my_level] = afterTriggers->firing_counter;
2700 }
2701
2702 /*
2703  * AfterTriggerEndSubXact()
2704  *
2705  *      The current subtransaction is ending.
2706  */
2707 void
2708 AfterTriggerEndSubXact(bool isCommit)
2709 {
2710         int                     my_level = GetCurrentTransactionNestLevel();
2711         SetConstraintState state;
2712         AfterTriggerEvent event;
2713         CommandId       subxact_firing_id;
2714
2715         /*
2716          * Ignore call if the transaction is in aborted state.  (Probably
2717          * unneeded)
2718          */
2719         if (afterTriggers == NULL)
2720                 return;
2721
2722         /*
2723          * Pop the prior state if needed.
2724          */
2725         Assert(my_level < afterTriggers->maxtransdepth);
2726
2727         if (isCommit)
2728         {
2729                 /* If we saved a prior state, we don't need it anymore */
2730                 state = afterTriggers->state_stack[my_level];
2731                 if (state != NULL)
2732                         pfree(state);
2733                 /* this avoids double pfree if error later: */
2734                 afterTriggers->state_stack[my_level] = NULL;
2735                 Assert(afterTriggers->query_depth ==
2736                            afterTriggers->depth_stack[my_level]);
2737         }
2738         else
2739         {
2740                 /*
2741                  * Aborting --- restore the pointers from the stacks.
2742                  */
2743                 afterTriggers->events = afterTriggers->events_stack[my_level];
2744                 afterTriggers->query_depth = afterTriggers->depth_stack[my_level];
2745
2746                 /*
2747                  * Cleanup the tail of the list.
2748                  */
2749                 if (afterTriggers->events.tail != NULL)
2750                         afterTriggers->events.tail->ate_next = NULL;
2751
2752                 /*
2753                  * We don't need to free the subtransaction's items, since the
2754                  * CurTransactionContext will be reset shortly.
2755                  */
2756
2757                 /*
2758                  * Restore the trigger state.  If the saved state is NULL, then this
2759                  * subxact didn't save it, so it doesn't need restoring.
2760                  */
2761                 state = afterTriggers->state_stack[my_level];
2762                 if (state != NULL)
2763                 {
2764                         pfree(afterTriggers->state);
2765                         afterTriggers->state = state;
2766                 }
2767                 /* this avoids double pfree if error later: */
2768                 afterTriggers->state_stack[my_level] = NULL;
2769
2770                 /*
2771                  * Scan for any remaining deferred events that were marked DONE or IN
2772                  * PROGRESS by this subxact or a child, and un-mark them. We can
2773                  * recognize such events because they have a firing ID greater than or
2774                  * equal to the firing_counter value we saved at subtransaction start.
2775                  * (This essentially assumes that the current subxact includes all
2776                  * subxacts started after it.)
2777                  */
2778                 subxact_firing_id = afterTriggers->firing_stack[my_level];
2779                 for (event = afterTriggers->events.head;
2780                          event != NULL;
2781                          event = event->ate_next)
2782                 {
2783                         if (event->ate_event &
2784                                 (AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS))
2785                         {
2786                                 if (event->ate_firing_id >= subxact_firing_id)
2787                                         event->ate_event &=
2788                                                 ~(AFTER_TRIGGER_DONE | AFTER_TRIGGER_IN_PROGRESS);
2789                         }
2790                 }
2791         }
2792 }
2793
2794 /*
2795  * Create an empty SetConstraintState with room for numalloc trigstates
2796  */
2797 static SetConstraintState
2798 SetConstraintStateCreate(int numalloc)
2799 {
2800         SetConstraintState state;
2801
2802         /* Behave sanely with numalloc == 0 */
2803         if (numalloc <= 0)
2804                 numalloc = 1;
2805
2806         /*
2807          * We assume that zeroing will correctly initialize the state values.
2808          */
2809         state = (SetConstraintState)
2810                 MemoryContextAllocZero(TopTransactionContext,
2811                                                            sizeof(SetConstraintStateData) +
2812                                                    (numalloc - 1) *sizeof(SetConstraintTriggerData));
2813
2814         state->numalloc = numalloc;
2815
2816         return state;
2817 }
2818
2819 /*
2820  * Copy a SetConstraintState
2821  */
2822 static SetConstraintState
2823 SetConstraintStateCopy(SetConstraintState origstate)
2824 {
2825         SetConstraintState state;
2826
2827         state = SetConstraintStateCreate(origstate->numstates);
2828
2829         state->all_isset = origstate->all_isset;
2830         state->all_isdeferred = origstate->all_isdeferred;
2831         state->numstates = origstate->numstates;
2832         memcpy(state->trigstates, origstate->trigstates,
2833                    origstate->numstates * sizeof(SetConstraintTriggerData));
2834
2835         return state;
2836 }
2837
2838 /*
2839  * Add a per-trigger item to a SetConstraintState.      Returns possibly-changed
2840  * pointer to the state object (it will change if we have to repalloc).
2841  */
2842 static SetConstraintState
2843 SetConstraintStateAddItem(SetConstraintState state,
2844                                                   Oid tgoid, bool tgisdeferred)
2845 {
2846         if (state->numstates >= state->numalloc)
2847         {
2848                 int                     newalloc = state->numalloc * 2;
2849
2850                 newalloc = Max(newalloc, 8);    /* in case original has size 0 */
2851                 state = (SetConstraintState)
2852                         repalloc(state,
2853                                          sizeof(SetConstraintStateData) +
2854                                          (newalloc - 1) *sizeof(SetConstraintTriggerData));
2855                 state->numalloc = newalloc;
2856                 Assert(state->numstates < state->numalloc);
2857         }
2858
2859         state->trigstates[state->numstates].sct_tgoid = tgoid;
2860         state->trigstates[state->numstates].sct_tgisdeferred = tgisdeferred;
2861         state->numstates++;
2862
2863         return state;
2864 }
2865
2866 /* ----------
2867  * AfterTriggerSetState()
2868  *
2869  *      Execute the SET CONSTRAINTS ... utility command.
2870  * ----------
2871  */
2872 void
2873 AfterTriggerSetState(ConstraintsSetStmt *stmt)
2874 {
2875         int                     my_level = GetCurrentTransactionNestLevel();
2876
2877         /*
2878          * Ignore call if we aren't in a transaction.  (Shouldn't happen?)
2879          */
2880         if (afterTriggers == NULL)
2881                 return;
2882
2883         /*
2884          * If in a subtransaction, and we didn't save the current state already,
2885          * save it so it can be restored if the subtransaction aborts.
2886          */
2887         if (my_level > 1 &&
2888                 afterTriggers->state_stack[my_level] == NULL)
2889         {
2890                 afterTriggers->state_stack[my_level] =
2891                         SetConstraintStateCopy(afterTriggers->state);
2892         }
2893
2894         /*
2895          * Handle SET CONSTRAINTS ALL ...
2896          */
2897         if (stmt->constraints == NIL)
2898         {
2899                 /*
2900                  * Forget any previous SET CONSTRAINTS commands in this transaction.
2901                  */
2902                 afterTriggers->state->numstates = 0;
2903
2904                 /*
2905                  * Set the per-transaction ALL state to known.
2906                  */
2907                 afterTriggers->state->all_isset = true;
2908                 afterTriggers->state->all_isdeferred = stmt->deferred;
2909         }
2910         else
2911         {
2912                 Relation        tgrel;
2913                 ListCell   *l;
2914                 List       *oidlist = NIL;
2915
2916                 /* ----------
2917                  * Handle SET CONSTRAINTS constraint-name [, ...]
2918                  * First lookup all trigger Oid's for the constraint names.
2919                  * ----------
2920                  */
2921                 tgrel = heap_open(TriggerRelationId, AccessShareLock);
2922
2923                 foreach(l, stmt->constraints)
2924                 {
2925                         char       *cname = strVal(lfirst(l));
2926                         ScanKeyData skey;
2927                         SysScanDesc tgscan;
2928                         HeapTuple       htup;
2929                         bool            found;
2930
2931                         /*
2932                          * Check that only named constraints are set explicitly
2933                          */
2934                         if (strlen(cname) == 0)
2935                                 ereport(ERROR,
2936                                                 (errcode(ERRCODE_INVALID_NAME),
2937                                         errmsg("unnamed constraints cannot be set explicitly")));
2938
2939                         /*
2940                          * Setup to scan pg_trigger by tgconstrname ...
2941                          */
2942                         ScanKeyInit(&skey,
2943                                                 Anum_pg_trigger_tgconstrname,
2944                                                 BTEqualStrategyNumber, F_NAMEEQ,
2945                                                 PointerGetDatum(cname));
2946
2947                         tgscan = systable_beginscan(tgrel, TriggerConstrNameIndexId, true,
2948                                                                                 SnapshotNow, 1, &skey);
2949
2950                         /*
2951                          * ... and search for the constraint trigger row
2952                          */
2953                         found = false;
2954
2955                         while (HeapTupleIsValid(htup = systable_getnext(tgscan)))
2956                         {
2957                                 Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(htup);
2958
2959                                 /*
2960                                  * If we found some, check that they fit the deferrability but
2961                                  * skip referential action ones, since they are silently never
2962                                  * deferrable.
2963                                  */
2964                                 if (pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_UPD &&
2965                                         pg_trigger->tgfoid != F_RI_FKEY_RESTRICT_DEL &&
2966                                         pg_trigger->tgfoid != F_RI_FKEY_CASCADE_UPD &&
2967                                         pg_trigger->tgfoid != F_RI_FKEY_CASCADE_DEL &&
2968                                         pg_trigger->tgfoid != F_RI_FKEY_SETNULL_UPD &&
2969                                         pg_trigger->tgfoid != F_RI_FKEY_SETNULL_DEL &&
2970                                         pg_trigger->tgfoid != F_RI_FKEY_SETDEFAULT_UPD &&
2971                                         pg_trigger->tgfoid != F_RI_FKEY_SETDEFAULT_DEL)
2972                                 {
2973                                         if (stmt->deferred && !pg_trigger->tgdeferrable)
2974                                                 ereport(ERROR,
2975                                                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
2976                                                                  errmsg("constraint \"%s\" is not deferrable",
2977                                                                                 cname)));
2978                                         oidlist = lappend_oid(oidlist, HeapTupleGetOid(htup));
2979                                 }
2980                                 found = true;
2981                         }
2982
2983                         systable_endscan(tgscan);
2984
2985                         /*
2986                          * Not found ?
2987                          */
2988                         if (!found)
2989                                 ereport(ERROR,
2990                                                 (errcode(ERRCODE_UNDEFINED_OBJECT),
2991                                                  errmsg("constraint \"%s\" does not exist",
2992                                                                 cname)));
2993                 }
2994                 heap_close(tgrel, AccessShareLock);
2995
2996                 /*
2997                  * Set the trigger states of individual triggers for this xact.
2998                  */
2999                 foreach(l, oidlist)
3000                 {
3001                         Oid                     tgoid = lfirst_oid(l);
3002                         SetConstraintState state = afterTriggers->state;
3003                         bool            found = false;
3004                         int                     i;
3005
3006                         for (i = 0; i < state->numstates; i++)
3007                         {
3008                                 if (state->trigstates[i].sct_tgoid == tgoid)
3009                                 {
3010                                         state->trigstates[i].sct_tgisdeferred = stmt->deferred;
3011                                         found = true;
3012                                         break;
3013                                 }
3014                         }
3015                         if (!found)
3016                         {
3017                                 afterTriggers->state =
3018                                         SetConstraintStateAddItem(state, tgoid, stmt->deferred);
3019                         }
3020                 }
3021         }
3022
3023         /*
3024          * SQL99 requires that when a constraint is set to IMMEDIATE, any deferred
3025          * checks against that constraint must be made when the SET CONSTRAINTS
3026          * command is executed -- i.e. the effects of the SET CONSTRAINTS command
3027          * apply retroactively.  We've updated the constraints state, so scan the
3028          * list of previously deferred events to fire any that have now become
3029          * immediate.
3030          *
3031          * Obviously, if this was SET ... DEFERRED then it can't have converted
3032          * any unfired events to immediate, so we need do nothing in that case.
3033          */
3034         if (!stmt->deferred)
3035         {
3036                 AfterTriggerEventList *events = &afterTriggers->events;
3037
3038                 if (afterTriggerMarkEvents(events, NULL, true))
3039                 {
3040                         CommandId       firing_id = afterTriggers->firing_counter++;
3041
3042                         /*
3043                          * We can delete fired events if we are at top transaction level,
3044                          * but we'd better not if inside a subtransaction, since the
3045                          * subtransaction could later get rolled back.
3046                          */
3047                         afterTriggerInvokeEvents(events, firing_id, NULL,
3048                                                                          !IsSubTransaction());
3049                 }
3050         }
3051 }
3052
3053
3054 /* ----------
3055  * AfterTriggerSaveEvent()
3056  *
3057  *      Called by ExecA[RS]...Triggers() to add the event to the queue.
3058  *
3059  *      NOTE: should be called only if we've determined that an event must
3060  *      be added to the queue.
3061  * ----------
3062  */
3063 static void
3064 AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event, bool row_trigger,
3065                                           HeapTuple oldtup, HeapTuple newtup)
3066 {
3067         Relation        rel = relinfo->ri_RelationDesc;
3068         TriggerDesc *trigdesc = relinfo->ri_TrigDesc;
3069         AfterTriggerEvent new_event;
3070         int                     i;
3071         int                     ntriggers;
3072         int                *tgindx;
3073         ItemPointerData oldctid;
3074         ItemPointerData newctid;
3075
3076         if (afterTriggers == NULL)
3077                 elog(ERROR, "AfterTriggerSaveEvent() called outside of transaction");
3078
3079         /*
3080          * Get the CTID's of OLD and NEW
3081          */
3082         if (oldtup != NULL)
3083                 ItemPointerCopy(&(oldtup->t_self), &(oldctid));
3084         else
3085                 ItemPointerSetInvalid(&(oldctid));
3086         if (newtup != NULL)
3087                 ItemPointerCopy(&(newtup->t_self), &(newctid));
3088         else
3089                 ItemPointerSetInvalid(&(newctid));
3090
3091         /*
3092          * Scan the appropriate set of triggers
3093          */
3094         if (row_trigger)
3095         {
3096                 ntriggers = trigdesc->n_after_row[event];
3097                 tgindx = trigdesc->tg_after_row[event];
3098         }
3099         else
3100         {
3101                 ntriggers = trigdesc->n_after_statement[event];
3102                 tgindx = trigdesc->tg_after_statement[event];
3103         }
3104
3105         for (i = 0; i < ntriggers; i++)
3106         {
3107                 Trigger    *trigger = &trigdesc->triggers[tgindx[i]];
3108
3109                 /* Ignore disabled triggers */
3110                 if (!trigger->tgenabled)
3111                         continue;
3112
3113                 /*
3114                  * If this is an UPDATE of a PK table or FK table that does not change
3115                  * the PK or FK respectively, we can skip queuing the event: there is
3116                  * no need to fire the trigger.
3117                  */
3118                 if ((event & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_UPDATE)
3119                 {
3120                         switch (RI_FKey_trigger_type(trigger->tgfoid))
3121                         {
3122                                 case RI_TRIGGER_PK:
3123                                         /* Update on PK table */
3124                                         if (RI_FKey_keyequal_upd_pk(trigger, rel, oldtup, newtup))
3125                                         {
3126                                                 /* key unchanged, so skip queuing this event */
3127                                                 continue;
3128                                         }
3129                                         break;
3130
3131                                 case RI_TRIGGER_FK:
3132
3133                                         /*
3134                                          * Update on FK table
3135                                          *
3136                                          * There is one exception when updating FK tables: if the
3137                                          * updated row was inserted by our own transaction and the
3138                                          * FK is deferred, we still need to fire the trigger. This
3139                                          * is because our UPDATE will invalidate the INSERT so the
3140                                          * end-of-transaction INSERT RI trigger will not do
3141                                          * anything, so we have to do the check for the UPDATE
3142                                          * anyway.
3143                                          */
3144                                         if (HeapTupleHeaderGetXmin(oldtup->t_data) !=
3145                                                 GetCurrentTransactionId() &&
3146                                                 RI_FKey_keyequal_upd_fk(trigger, rel, oldtup, newtup))
3147                                         {
3148                                                 continue;
3149                                         }
3150                                         break;
3151
3152                                 case RI_TRIGGER_NONE:
3153                                         /* Not an FK trigger */
3154                                         break;
3155                         }
3156                 }
3157
3158                 /*
3159                  * Create a new event.  We use the CurTransactionContext so the event
3160                  * will automatically go away if the subtransaction aborts.
3161                  */
3162                 new_event = (AfterTriggerEvent)
3163                         MemoryContextAlloc(CurTransactionContext,
3164                                                            sizeof(AfterTriggerEventData));
3165                 new_event->ate_next = NULL;
3166                 new_event->ate_event =
3167                         (event & TRIGGER_EVENT_OPMASK) |
3168                         (row_trigger ? TRIGGER_EVENT_ROW : 0) |
3169                         (trigger->tgdeferrable ? AFTER_TRIGGER_DEFERRABLE : 0) |
3170                         (trigger->tginitdeferred ? AFTER_TRIGGER_INITDEFERRED : 0);
3171                 new_event->ate_firing_id = 0;
3172                 new_event->ate_tgoid = trigger->tgoid;
3173                 new_event->ate_relid = rel->rd_id;
3174                 ItemPointerCopy(&oldctid, &(new_event->ate_oldctid));
3175                 ItemPointerCopy(&newctid, &(new_event->ate_newctid));
3176
3177                 /*
3178                  * Add the new event to the queue.
3179                  */
3180                 afterTriggerAddEvent(new_event);
3181         }
3182 }