---------- * AfterTriggerEndQuery() * * Called after one query has been completely processed. At this time * we invoke all AFTER IMMEDIATE trigger events queued by the query, and * transfer deferred trigger events to the global deferred-trigger list. * * Note that this must be called BEFORE closing down the executor * with ExecutorEnd, because we make use of the EState's info about * targ
| 4766 | * ---------- |
| 4767 | */ |
| 4768 | void |
| 4769 | AfterTriggerEndQuery(EState *estate) |
| 4770 | { |
| 4771 | AfterTriggersQueryData *qs; |
| 4772 | |
| 4773 | /* Must be inside a query, too */ |
| 4774 | Assert(afterTriggers.query_depth >= 0); |
| 4775 | |
| 4776 | /* |
| 4777 | * If we never even got as far as initializing the event stack, there |
| 4778 | * certainly won't be any events, so exit quickly. |
| 4779 | */ |
| 4780 | if (afterTriggers.query_depth >= afterTriggers.maxquerydepth) |
| 4781 | { |
| 4782 | afterTriggers.query_depth--; |
| 4783 | return; |
| 4784 | } |
| 4785 | |
| 4786 | /* |
| 4787 | * Process all immediate-mode triggers queued by the query, and move the |
| 4788 | * deferred ones to the main list of deferred events. |
| 4789 | * |
| 4790 | * Notice that we decide which ones will be fired, and put the deferred |
| 4791 | * ones on the main list, before anything is actually fired. This ensures |
| 4792 | * reasonably sane behavior if a trigger function does SET CONSTRAINTS ... |
| 4793 | * IMMEDIATE: all events we have decided to defer will be available for it |
| 4794 | * to fire. |
| 4795 | * |
| 4796 | * We loop in case a trigger queues more events at the same query level. |
| 4797 | * Ordinary trigger functions, including all PL/pgSQL trigger functions, |
| 4798 | * will instead fire any triggers in a dedicated query level. Foreign key |
| 4799 | * enforcement triggers do add to the current query level, thanks to their |
| 4800 | * passing fire_triggers = false to SPI_execute_snapshot(). Other |
| 4801 | * C-language triggers might do likewise. |
| 4802 | * |
| 4803 | * If we find no firable events, we don't have to increment |
| 4804 | * firing_counter. |
| 4805 | */ |
| 4806 | qs = &afterTriggers.query_stack[afterTriggers.query_depth]; |
| 4807 | |
| 4808 | for (;;) |
| 4809 | { |
| 4810 | if (afterTriggerMarkEvents(&qs->events, &afterTriggers.events, true)) |
| 4811 | { |
| 4812 | CommandId firing_id = afterTriggers.firing_counter++; |
| 4813 | AfterTriggerEventChunk *oldtail = qs->events.tail; |
| 4814 | |
| 4815 | if (afterTriggerInvokeEvents(&qs->events, firing_id, estate, false)) |
| 4816 | break; /* all fired */ |
| 4817 | |
| 4818 | /* |
| 4819 | * Firing a trigger could result in query_stack being repalloc'd, |
| 4820 | * so we must recalculate qs after each afterTriggerInvokeEvents |
| 4821 | * call. Furthermore, it's unsafe to pass delete_ok = true here, |
| 4822 | * because that could cause afterTriggerInvokeEvents to try to |
| 4823 | * access qs->events after the stack has been repalloc'd. |
| 4824 | */ |
| 4825 | qs = &afterTriggers.query_stack[afterTriggers.query_depth]; |
no test coverage detected