aboutsummaryrefslogtreecommitdiff
path: root/src/pl/plpython/plpy_exec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl/plpython/plpy_exec.c')
-rw-r--r--src/pl/plpython/plpy_exec.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/pl/plpython/plpy_exec.c b/src/pl/plpython/plpy_exec.c
index 3145c696996..6f7b5e121d6 100644
--- a/src/pl/plpython/plpy_exec.c
+++ b/src/pl/plpython/plpy_exec.c
@@ -335,6 +335,13 @@ PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
PLy_output_setup_tuple(&proc->result, rel_descr, proc);
PLy_input_setup_tuple(&proc->result_in, rel_descr, proc);
+ /*
+ * If the trigger is called recursively, we must push outer-level
+ * arguments into the stack. This must be immediately before the PG_TRY
+ * to ensure that the corresponding pop happens.
+ */
+ PLy_global_args_push(proc);
+
PG_TRY();
{
int rc PG_USED_FOR_ASSERTS_ONLY;
@@ -397,6 +404,7 @@ PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc)
}
PG_FINALLY();
{
+ PLy_global_args_pop(proc);
Py_XDECREF(plargs);
Py_XDECREF(plrv);
}
@@ -501,6 +509,13 @@ PLy_function_save_args(PLyProcedure *proc)
result->args = PyDict_GetItemString(proc->globals, "args");
Py_XINCREF(result->args);
+ /* If it's a trigger, also save "TD" */
+ if (proc->is_trigger)
+ {
+ result->td = PyDict_GetItemString(proc->globals, "TD");
+ Py_XINCREF(result->td);
+ }
+
/* Fetch all the named arguments */
if (proc->argnames)
{
@@ -550,6 +565,13 @@ PLy_function_restore_args(PLyProcedure *proc, PLySavedArgs *savedargs)
Py_DECREF(savedargs->args);
}
+ /* Restore the "TD" object, too */
+ if (savedargs->td)
+ {
+ PyDict_SetItemString(proc->globals, "TD", savedargs->td);
+ Py_DECREF(savedargs->td);
+ }
+
/* And free the PLySavedArgs struct */
pfree(savedargs);
}
@@ -568,8 +590,9 @@ PLy_function_drop_args(PLySavedArgs *savedargs)
Py_XDECREF(savedargs->namedargs[i]);
}
- /* Drop ref to the "args" object, too */
+ /* Drop refs to the "args" and "TD" objects, too */
Py_XDECREF(savedargs->args);
+ Py_XDECREF(savedargs->td);
/* And free the PLySavedArgs struct */
pfree(savedargs);
@@ -578,9 +601,9 @@ PLy_function_drop_args(PLySavedArgs *savedargs)
/*
* Save away any existing arguments for the given procedure, so that we can
* install new values for a recursive call. This should be invoked before
- * doing PLy_function_build_args().
+ * doing PLy_function_build_args() or PLy_trigger_build_args().
*
- * NB: caller must ensure that PLy_global_args_pop gets invoked once, and
+ * NB: callers must ensure that PLy_global_args_pop gets invoked once, and
* only once, per successful completion of PLy_global_args_push. Otherwise
* we'll end up out-of-sync between the actual call stack and the contents
* of proc->argstack.