diff options
Diffstat (limited to 'src/pl/plpython/plpy_exec.c')
-rw-r--r-- | src/pl/plpython/plpy_exec.c | 29 |
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. |