* afterTriggerInvokeEvents() * * Scan the given event list for events that are marked as to be fired * in the current firing cycle, and fire them. query_depth is the index in * afterTriggers->query_stack, or -1 to examine afterTriggers->events. * (We have to be careful here because query_stack could move under us.) * * If estate isn't NULL, we use its result relation info to avoid repeated
| 4283 | * to avoid repeating afterTriggerMarkEvents). |
| 4284 | */ |
| 4285 | static bool |
| 4286 | afterTriggerInvokeEvents(AfterTriggerEventList *events, |
| 4287 | CommandId firing_id, |
| 4288 | EState *estate, |
| 4289 | bool delete_ok) |
| 4290 | { |
| 4291 | bool all_fired = true; |
| 4292 | AfterTriggerEventChunk *chunk; |
| 4293 | MemoryContext per_tuple_context; |
| 4294 | bool local_estate = false; |
| 4295 | ResultRelInfo *rInfo = NULL; |
| 4296 | Relation rel = NULL; |
| 4297 | TriggerDesc *trigdesc = NULL; |
| 4298 | FmgrInfo *finfo = NULL; |
| 4299 | Instrumentation *instr = NULL; |
| 4300 | TupleTableSlot *slot1 = NULL, |
| 4301 | *slot2 = NULL; |
| 4302 | |
| 4303 | /* Make a local EState if need be */ |
| 4304 | if (estate == NULL) |
| 4305 | { |
| 4306 | estate = CreateExecutorState(); |
| 4307 | local_estate = true; |
| 4308 | } |
| 4309 | |
| 4310 | /* Make a per-tuple memory context for trigger function calls */ |
| 4311 | per_tuple_context = |
| 4312 | AllocSetContextCreate(CurrentMemoryContext, |
| 4313 | "AfterTriggerTupleContext", |
| 4314 | ALLOCSET_DEFAULT_SIZES); |
| 4315 | |
| 4316 | for_each_chunk(chunk, *events) |
| 4317 | { |
| 4318 | AfterTriggerEvent event; |
| 4319 | bool all_fired_in_chunk = true; |
| 4320 | |
| 4321 | for_each_event(event, chunk) |
| 4322 | { |
| 4323 | AfterTriggerShared evtshared = GetTriggerSharedData(event); |
| 4324 | |
| 4325 | /* |
| 4326 | * Is it one for me to fire? |
| 4327 | */ |
| 4328 | if ((event->ate_flags & AFTER_TRIGGER_IN_PROGRESS) && |
| 4329 | evtshared->ats_firing_id == firing_id) |
| 4330 | { |
| 4331 | /* |
| 4332 | * So let's fire it... but first, find the correct relation if |
| 4333 | * this is not the same relation as before. |
| 4334 | */ |
| 4335 | if (rel == NULL || RelationGetRelid(rel) != evtshared->ats_relid) |
| 4336 | { |
| 4337 | rInfo = ExecGetTriggerResultRel(estate, evtshared->ats_relid); |
| 4338 | rel = rInfo->ri_RelationDesc; |
| 4339 | /* Catch calls with insufficient relcache refcounting */ |
| 4340 | Assert(!RelationHasReferenceCountZero(rel)); |
| 4341 | trigdesc = rInfo->ri_TrigDesc; |
| 4342 | finfo = rInfo->ri_TrigFunctions; |
no test coverage detected