MCPcopy Create free account
hub / github.com/apache/cloudberry / PLy_exec_trigger

Function PLy_exec_trigger

src/pl/plpython/plpy_exec.c:320–434  ·  view source on GitHub ↗

trigger subhandler * * the python function is expected to return Py_None if the tuple is * acceptable and unmodified. Otherwise it should return a PyString * object who's value is SKIP, or MODIFY. SKIP means don't perform * this action. MODIFY means the tuple has been modified, so update * tuple and perform action. SKIP and MODIFY assume the trigger fires * BEFORE the event and is ROW l

Source from the content-addressed store, hash-verified

318 * to take no arguments and return an argument of type trigger.
319 */
320HeapTuple
321PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
322{
323 HeapTuple rv = NULL;
324 PyObject *volatile plargs = NULL;
325 PyObject *volatile plrv = NULL;
326 TriggerData *tdata;
327 TupleDesc rel_descr;
328
329 Assert(CALLED_AS_TRIGGER(fcinfo));
330 tdata = (TriggerData *) fcinfo->context;
331
332 /*
333 * Input/output conversion for trigger tuples. We use the result and
334 * result_in fields to store the tuple conversion info. We do this over
335 * again on each call to cover the possibility that the relation's tupdesc
336 * changed since the trigger was last called. The PLy_xxx_setup_func
337 * calls should only happen once, but PLy_input_setup_tuple and
338 * PLy_output_setup_tuple are responsible for not doing repetitive work.
339 */
340 rel_descr = RelationGetDescr(tdata->tg_relation);
341 if (proc->result.typoid != rel_descr->tdtypeid)
342 PLy_output_setup_func(&proc->result, proc->mcxt,
343 rel_descr->tdtypeid,
344 rel_descr->tdtypmod,
345 proc);
346 if (proc->result_in.typoid != rel_descr->tdtypeid)
347 PLy_input_setup_func(&proc->result_in, proc->mcxt,
348 rel_descr->tdtypeid,
349 rel_descr->tdtypmod,
350 proc);
351 PLy_output_setup_tuple(&proc->result, rel_descr, proc);
352 PLy_input_setup_tuple(&proc->result_in, rel_descr, proc);
353
354 /*
355 * If the trigger is called recursively, we must push outer-level
356 * arguments into the stack. This must be immediately before the PG_TRY
357 * to ensure that the corresponding pop happens.
358 */
359 PLy_global_args_push(proc);
360
361 PG_TRY();
362 {
363 int rc PG_USED_FOR_ASSERTS_ONLY;
364
365 rc = SPI_register_trigger_data(tdata);
366 Assert(rc >= 0);
367
368 plargs = PLy_trigger_build_args(fcinfo, proc, &rv);
369 plrv = PLy_procedure_call(proc, "TD", plargs);
370
371 Assert(plrv != NULL);
372
373 /*
374 * Disconnect from SPI manager
375 */
376 if (SPI_finish() != SPI_OK_FINISH)
377 elog(ERROR, "SPI_finish failed");

Callers 1

plpython_call_handlerFunction · 0.85

Calls 15

PLy_output_setup_funcFunction · 0.85
PLy_input_setup_funcFunction · 0.85
PLy_output_setup_tupleFunction · 0.85
PLy_input_setup_tupleFunction · 0.85
PLy_global_args_pushFunction · 0.85
PLy_trigger_build_argsFunction · 0.85
PLy_procedure_callFunction · 0.85
SPI_finishFunction · 0.85
PLyUnicode_AsStringFunction · 0.85
pg_strcasecmpFunction · 0.85
PLy_modify_tupleFunction · 0.85

Tested by

no test coverage detected