* Call a trigger function. * * trigdata: trigger descriptor. * tgindx: trigger's index in finfo and instr arrays. * finfo: array of cached trigger function call information. * instr: optional array of EXPLAIN ANALYZE instrumentation state. * per_tuple_context: memory context to execute the function in. * * Returns the tuple (or NULL) as returned by the function. */
| 2178 | * Returns the tuple (or NULL) as returned by the function. |
| 2179 | */ |
| 2180 | static HeapTuple |
| 2181 | ExecCallTriggerFunc(TriggerData *trigdata, |
| 2182 | int tgindx, |
| 2183 | FmgrInfo *finfo, |
| 2184 | Instrumentation *instr, |
| 2185 | MemoryContext per_tuple_context) |
| 2186 | { |
| 2187 | LOCAL_FCINFO(fcinfo, 0); |
| 2188 | PgStat_FunctionCallUsage fcusage; |
| 2189 | Datum result; |
| 2190 | MemoryContext oldContext; |
| 2191 | |
| 2192 | /* |
| 2193 | * Protect against code paths that may fail to initialize transition table |
| 2194 | * info. |
| 2195 | */ |
| 2196 | Assert(((TRIGGER_FIRED_BY_INSERT(trigdata->tg_event) || |
| 2197 | TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event) || |
| 2198 | TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) && |
| 2199 | TRIGGER_FIRED_AFTER(trigdata->tg_event) && |
| 2200 | !(trigdata->tg_event & AFTER_TRIGGER_DEFERRABLE) && |
| 2201 | !(trigdata->tg_event & AFTER_TRIGGER_INITDEFERRED)) || |
| 2202 | (trigdata->tg_oldtable == NULL && trigdata->tg_newtable == NULL)); |
| 2203 | |
| 2204 | finfo += tgindx; |
| 2205 | |
| 2206 | /* |
| 2207 | * We cache fmgr lookup info, to avoid making the lookup again on each |
| 2208 | * call. |
| 2209 | */ |
| 2210 | if (finfo->fn_oid == InvalidOid) |
| 2211 | fmgr_info(trigdata->tg_trigger->tgfoid, finfo); |
| 2212 | |
| 2213 | Assert(finfo->fn_oid == trigdata->tg_trigger->tgfoid); |
| 2214 | |
| 2215 | /* |
| 2216 | * If doing EXPLAIN ANALYZE, start charging time to this trigger. |
| 2217 | */ |
| 2218 | if (instr) |
| 2219 | InstrStartNode(instr + tgindx); |
| 2220 | |
| 2221 | /* |
| 2222 | * Do the function evaluation in the per-tuple memory context, so that |
| 2223 | * leaked memory will be reclaimed once per tuple. Note in particular that |
| 2224 | * any new tuple created by the trigger function will live till the end of |
| 2225 | * the tuple cycle. |
| 2226 | */ |
| 2227 | oldContext = MemoryContextSwitchTo(per_tuple_context); |
| 2228 | |
| 2229 | /* |
| 2230 | * Call the function, passing no arguments but setting a context. |
| 2231 | */ |
| 2232 | InitFunctionCallInfoData(*fcinfo, finfo, 0, |
| 2233 | InvalidOid, (Node *) trigdata, NULL); |
| 2234 | |
| 2235 | pgstat_init_function_usage(fcinfo, &fcusage); |
| 2236 | |
| 2237 | MyTriggerDepth++; |
no test coverage detected