---------- * AfterTriggerExecute() * * Fetch the required tuples back from the heap and fire one * single trigger function. * * Frequently, this will be fired many times in a row for triggers of * a single relation. Therefore, we cache the open relation and provide * fmgr lookup cache space at the caller level. (For triggers fired at * the end of a query, we can even piggyback on the ex
| 3983 | * ---------- |
| 3984 | */ |
| 3985 | static void |
| 3986 | AfterTriggerExecute(EState *estate, |
| 3987 | AfterTriggerEvent event, |
| 3988 | ResultRelInfo *relInfo, |
| 3989 | TriggerDesc *trigdesc, |
| 3990 | FmgrInfo *finfo, Instrumentation *instr, |
| 3991 | MemoryContext per_tuple_context, |
| 3992 | TupleTableSlot *trig_tuple_slot1, |
| 3993 | TupleTableSlot *trig_tuple_slot2) |
| 3994 | { |
| 3995 | Relation rel = relInfo->ri_RelationDesc; |
| 3996 | AfterTriggerShared evtshared = GetTriggerSharedData(event); |
| 3997 | Oid tgoid = evtshared->ats_tgoid; |
| 3998 | TriggerData LocTriggerData = {0}; |
| 3999 | HeapTuple rettuple; |
| 4000 | int tgindx; |
| 4001 | bool should_free_trig = false; |
| 4002 | bool should_free_new = false; |
| 4003 | |
| 4004 | /* |
| 4005 | * Locate trigger in trigdesc. |
| 4006 | */ |
| 4007 | for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++) |
| 4008 | { |
| 4009 | if (trigdesc->triggers[tgindx].tgoid == tgoid) |
| 4010 | { |
| 4011 | LocTriggerData.tg_trigger = &(trigdesc->triggers[tgindx]); |
| 4012 | break; |
| 4013 | } |
| 4014 | } |
| 4015 | if (LocTriggerData.tg_trigger == NULL) |
| 4016 | elog(ERROR, "could not find trigger %u", tgoid); |
| 4017 | |
| 4018 | /* |
| 4019 | * If doing EXPLAIN ANALYZE, start charging time to this trigger. We want |
| 4020 | * to include time spent re-fetching tuples in the trigger cost. |
| 4021 | */ |
| 4022 | if (instr) |
| 4023 | InstrStartNode(instr + tgindx); |
| 4024 | |
| 4025 | /* |
| 4026 | * Fetch the required tuple(s). |
| 4027 | */ |
| 4028 | switch (event->ate_flags & AFTER_TRIGGER_TUP_BITS) |
| 4029 | { |
| 4030 | case AFTER_TRIGGER_FDW_FETCH: |
| 4031 | { |
| 4032 | Tuplestorestate *fdw_tuplestore = GetCurrentFDWTuplestore(); |
| 4033 | |
| 4034 | if (!tuplestore_gettupleslot(fdw_tuplestore, true, false, |
| 4035 | trig_tuple_slot1)) |
| 4036 | elog(ERROR, "failed to fetch tuple1 for AFTER trigger"); |
| 4037 | |
| 4038 | if ((evtshared->ats_event & TRIGGER_EVENT_OPMASK) == |
| 4039 | TRIGGER_EVENT_UPDATE && |
| 4040 | !tuplestore_gettupleslot(fdw_tuplestore, true, false, |
| 4041 | trig_tuple_slot2)) |
| 4042 | elog(ERROR, "failed to fetch tuple2 for AFTER trigger"); |
no test coverage detected