---------- * AfterTriggerFireDeferred() * * Called just before the current transaction is committed. At this * time we invoke all pending DEFERRED triggers. * * It is possible for other modules to queue additional deferred triggers * during pre-commit processing; therefore xact.c may have to call this * multiple times. * ---------- */
| 4928 | * ---------- |
| 4929 | */ |
| 4930 | void |
| 4931 | AfterTriggerFireDeferred(void) |
| 4932 | { |
| 4933 | AfterTriggerEventList *events; |
| 4934 | bool snap_pushed = false; |
| 4935 | |
| 4936 | /* Must not be inside a query */ |
| 4937 | Assert(afterTriggers.query_depth == -1); |
| 4938 | |
| 4939 | SIMPLE_FAULT_INJECTOR("after_trigger_fire_deferred"); |
| 4940 | /* |
| 4941 | * If there are any triggers to fire, make sure we have set a snapshot for |
| 4942 | * them to use. (Since PortalRunUtility doesn't set a snap for COMMIT, we |
| 4943 | * can't assume ActiveSnapshot is valid on entry.) |
| 4944 | */ |
| 4945 | events = &afterTriggers.events; |
| 4946 | if (events->head != NULL) |
| 4947 | { |
| 4948 | PushActiveSnapshot(GetTransactionSnapshot()); |
| 4949 | snap_pushed = true; |
| 4950 | } |
| 4951 | |
| 4952 | /* |
| 4953 | * Run all the remaining triggers. Loop until they are all gone, in case |
| 4954 | * some trigger queues more for us to do. |
| 4955 | */ |
| 4956 | while (afterTriggerMarkEvents(events, NULL, false)) |
| 4957 | { |
| 4958 | CommandId firing_id = afterTriggers.firing_counter++; |
| 4959 | |
| 4960 | if (afterTriggerInvokeEvents(events, firing_id, NULL, true)) |
| 4961 | break; /* all fired */ |
| 4962 | } |
| 4963 | |
| 4964 | /* |
| 4965 | * We don't bother freeing the event list, since it will go away anyway |
| 4966 | * (and more efficiently than via pfree) in AfterTriggerEndXact. |
| 4967 | */ |
| 4968 | |
| 4969 | if (snap_pushed) |
| 4970 | PopActiveSnapshot(); |
| 4971 | } |
| 4972 | |
| 4973 | |
| 4974 | /* ---------- |
no test coverage detected