diff options
Diffstat (limited to 'src/pl/plpython/plpy_exec.c')
-rw-r--r-- | src/pl/plpython/plpy_exec.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/src/pl/plpython/plpy_exec.c b/src/pl/plpython/plpy_exec.c index 30f929f220c..697726162a8 100644 --- a/src/pl/plpython/plpy_exec.c +++ b/src/pl/plpython/plpy_exec.c @@ -339,6 +339,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; @@ -405,6 +412,7 @@ PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc) } PG_CATCH(); { + PLy_global_args_pop(proc); Py_XDECREF(plargs); Py_XDECREF(plrv); @@ -412,6 +420,7 @@ PLy_exec_trigger(FunctionCallInfo fcinfo, PLyProcedure *proc) } PG_END_TRY(); + PLy_global_args_pop(proc); Py_DECREF(plargs); Py_DECREF(plrv); @@ -514,6 +523,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) { @@ -563,6 +579,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); } @@ -581,8 +604,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); @@ -591,9 +615,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. |