* Invoke each event trigger in a list of event triggers. */
| 870 | * Invoke each event trigger in a list of event triggers. |
| 871 | */ |
| 872 | static void |
| 873 | EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata) |
| 874 | { |
| 875 | MemoryContext context; |
| 876 | MemoryContext oldcontext; |
| 877 | ListCell *lc; |
| 878 | bool first = true; |
| 879 | |
| 880 | /* Guard against stack overflow due to recursive event trigger */ |
| 881 | check_stack_depth(); |
| 882 | |
| 883 | /* |
| 884 | * Let's evaluate event triggers in their own memory context, so that any |
| 885 | * leaks get cleaned up promptly. |
| 886 | */ |
| 887 | context = AllocSetContextCreate(CurrentMemoryContext, |
| 888 | "event trigger context", |
| 889 | ALLOCSET_DEFAULT_SIZES); |
| 890 | oldcontext = MemoryContextSwitchTo(context); |
| 891 | |
| 892 | /* Call each event trigger. */ |
| 893 | foreach(lc, fn_oid_list) |
| 894 | { |
| 895 | LOCAL_FCINFO(fcinfo, 0); |
| 896 | Oid fnoid = lfirst_oid(lc); |
| 897 | FmgrInfo flinfo; |
| 898 | PgStat_FunctionCallUsage fcusage; |
| 899 | |
| 900 | elog(DEBUG1, "EventTriggerInvoke %u", fnoid); |
| 901 | |
| 902 | /* |
| 903 | * We want each event trigger to be able to see the results of the |
| 904 | * previous event trigger's action. Caller is responsible for any |
| 905 | * command-counter increment that is needed between the event trigger |
| 906 | * and anything else in the transaction. |
| 907 | */ |
| 908 | if (first) |
| 909 | first = false; |
| 910 | else |
| 911 | CommandCounterIncrement(); |
| 912 | |
| 913 | /* Look up the function */ |
| 914 | fmgr_info(fnoid, &flinfo); |
| 915 | |
| 916 | /* Call the function, passing no arguments but setting a context. */ |
| 917 | InitFunctionCallInfoData(*fcinfo, &flinfo, 0, |
| 918 | InvalidOid, (Node *) trigdata, NULL); |
| 919 | pgstat_init_function_usage(fcinfo, &fcusage); |
| 920 | FunctionCallInvoke(fcinfo); |
| 921 | pgstat_end_function_usage(&fcusage, true); |
| 922 | |
| 923 | /* Reclaim memory. */ |
| 924 | MemoryContextReset(context); |
| 925 | } |
| 926 | |
| 927 | /* Restore old memory context and delete the temporary one. */ |
| 928 | MemoryContextSwitchTo(oldcontext); |
| 929 | MemoryContextDelete(context); |
no test coverage detected