> Yeah, you can't return or goto out of the PG_TRY part.
So this is a problem if the check would ever work.
(Sorry for such a delayed answer.)
Then we need to fix it. Attached is a minimal patch, which changes nothing
except for correct PG_TRY exiting.
Isn't it better this way?
CCing to Peter Eisentraut, whose patch originally introduced these returns.
Peter, will such a patch work somehow against your initial idea?
--
best regards,
Mikhail A. Gribkov
e-mail: [email protected]
*http://www.flickr.com/photos/youzhick/albums
<http://www.flickr.com/photos/youzhick/albums>*
http://www.strava.com/athletes/5085772
phone: +7(916)604-71-12
Telegram: @youzhick
On Sat, Oct 8, 2022 at 12:19 AM Tom Lane <[email protected]> wrote:
> Mikhail Gribkov <[email protected]> writes:
> > Usually it's not a good idea to exit PG_TRY() block via return statement.
> > Otherwise it would leave PG_exception_stack global variable in a wrong
> > state and next ereport() will jump to some junk address.
>
> Yeah, you can't return or goto out of the PG_TRY part.
>
> > Another suspicious case is PG_CATCH block in jsonb_plpython.c:
>
> This should be OK. The PG_CATCH and PG_FINALLY macros are set up so that
> we've fully restored that state *before* we execute any of the
> error-handling code. It would be basically impossible to have a guarantee
> that CATCH blocks never throw errors; they'd be so restricted as to be
> near useless, like signal handlers.
>
> regards, tom lane
>
diff --git a/src/pl/plpython/plpy_exec.c b/src/pl/plpython/plpy_exec.c
index 923703535a..0c8550e53c 100644
--- a/src/pl/plpython/plpy_exec.c
+++ b/src/pl/plpython/plpy_exec.c
@@ -418,7 +418,7 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc)
{
args = PyList_New(proc->nargs);
if (!args)
- return NULL;
+ goto end_of_try;
for (i = 0; i < proc->nargs; i++)
{
@@ -458,6 +458,7 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc)
/* cache the output conversion functions */
PLy_output_setup_record(&proc->result, desc, proc);
}
+end_of_try:
}
PG_CATCH();
{
@@ -694,7 +695,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r
{
pltdata = PyDict_New();
if (!pltdata)
- return NULL;
+ goto end_of_try;
pltname = PLyUnicode_FromString(tdata->tg_trigger->tgname);
PyDict_SetItemString(pltdata, "name", pltname);
@@ -839,7 +840,8 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r
if (!pltargs)
{
Py_DECREF(pltdata);
- return NULL;
+ pltdata = NULL;
+ goto end_of_try;
}
for (i = 0; i < tdata->tg_trigger->tgnargs; i++)
{
@@ -858,6 +860,7 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r
}
PyDict_SetItemString(pltdata, "args", pltargs);
Py_DECREF(pltargs);
+end_of_try:
}
PG_CATCH();
{