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