aboutsummaryrefslogtreecommitdiff
path: root/src/pl/plpython/plpy_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pl/plpython/plpy_main.c')
-rw-r--r--src/pl/plpython/plpy_main.c52
1 files changed, 26 insertions, 26 deletions
diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c
index 5dd86c6a8e5..4cfa2a8aeb1 100644
--- a/src/pl/plpython/plpy_main.c
+++ b/src/pl/plpython/plpy_main.c
@@ -257,23 +257,26 @@ plpython_call_handler(PG_FUNCTION_ARGS)
/*
* Push execution context onto stack. It is important that this get
* popped again, so avoid putting anything that could throw error between
- * here and the PG_TRY. (plpython_error_callback expects the stack entry
- * to be there, so we have to make the context first.)
+ * here and the PG_TRY.
*/
exec_ctx = PLy_push_execution_context();
- /*
- * Setup error traceback support for ereport()
- */
- plerrcontext.callback = plpython_error_callback;
- plerrcontext.previous = error_context_stack;
- error_context_stack = &plerrcontext;
-
PG_TRY();
{
Oid funcoid = fcinfo->flinfo->fn_oid;
PLyProcedure *proc;
+ /*
+ * Setup error traceback support for ereport(). Note that the PG_TRY
+ * structure pops this for us again at exit, so we needn't do that
+ * explicitly, nor do we risk the callback getting called after we've
+ * destroyed the exec_ctx.
+ */
+ plerrcontext.callback = plpython_error_callback;
+ plerrcontext.arg = exec_ctx;
+ plerrcontext.previous = error_context_stack;
+ error_context_stack = &plerrcontext;
+
if (CALLED_AS_TRIGGER(fcinfo))
{
Relation tgrel = ((TriggerData *) fcinfo->context)->tg_relation;
@@ -299,9 +302,7 @@ plpython_call_handler(PG_FUNCTION_ARGS)
}
PG_END_TRY();
- /* Pop the error context stack */
- error_context_stack = plerrcontext.previous;
- /* ... and then the execution context */
+ /* Destroy the execution context */
PLy_pop_execution_context();
return retval;
@@ -345,21 +346,22 @@ plpython_inline_handler(PG_FUNCTION_ARGS)
/*
* Push execution context onto stack. It is important that this get
* popped again, so avoid putting anything that could throw error between
- * here and the PG_TRY. (plpython_inline_error_callback doesn't currently
- * need the stack entry, but for consistency with plpython_call_handler we
- * do it in this order.)
+ * here and the PG_TRY.
*/
exec_ctx = PLy_push_execution_context();
- /*
- * Setup error traceback support for ereport()
- */
- plerrcontext.callback = plpython_inline_error_callback;
- plerrcontext.previous = error_context_stack;
- error_context_stack = &plerrcontext;
-
PG_TRY();
{
+ /*
+ * Setup error traceback support for ereport().
+ * plpython_inline_error_callback doesn't currently need exec_ctx, but
+ * for consistency with plpython_call_handler we do it the same way.
+ */
+ plerrcontext.callback = plpython_inline_error_callback;
+ plerrcontext.arg = exec_ctx;
+ plerrcontext.previous = error_context_stack;
+ error_context_stack = &plerrcontext;
+
PLy_procedure_compile(&proc, codeblock->source_text);
exec_ctx->curr_proc = &proc;
PLy_exec_function(&fake_fcinfo, &proc);
@@ -373,9 +375,7 @@ plpython_inline_handler(PG_FUNCTION_ARGS)
}
PG_END_TRY();
- /* Pop the error context stack */
- error_context_stack = plerrcontext.previous;
- /* ... and then the execution context */
+ /* Destroy the execution context */
PLy_pop_execution_context();
/* Now clean up the transient procedure we made */
@@ -403,7 +403,7 @@ PLy_procedure_is_trigger(Form_pg_proc procStruct)
static void
plpython_error_callback(void *arg)
{
- PLyExecutionContext *exec_ctx = PLy_current_execution_context();
+ PLyExecutionContext *exec_ctx = (PLyExecutionContext *) arg;
if (exec_ctx->curr_proc)
errcontext("PL/Python function \"%s\"",