Re: try/catch macros for Postgres backend - Mailing list pgsql-hackers

From Tom Lane
Subject Re: try/catch macros for Postgres backend
Date
Msg-id 12859.1091109017@sss.pgh.pa.us
Whole thread Raw
In response to Re: try/catch macros for Postgres backend  (Joe Conway <mail@joeconway.com>)
Responses Re: try/catch macros for Postgres backend  (Thomas Hallgren <thhal@mailblocks.com>)
List pgsql-hackers
Joe Conway <mail@joeconway.com> writes:
> This is especially a problem when the cleanup needs to be done inside 
> the embedded interpreter. I found that with R, I had to throw an error 
> in the R interpreter in order to allow the interpreter to clean up its 
> own state. That left me with code like this:
> [ snip ]
> Looks good to me, but I worry about being able to do what I've described 
> above. Basically I found that if I don't allow R to clean up after 
> itself by propagating the SPI call generated error into R, before 
> throwing a Postgres ERROR, I wind up with core dumps.

You could still do that, and perhaps even a bit more cleanly:
sqlErrorOccurred = false;PG_TRY();{    ans = R_tryEval(call, R_GlobalEnv, &errorOccurred);}PG_CATCH();{
sqlErrorOccurred= true;    /* push PG error into R machinery */    error("%s", "error executing SQL
statement");}PG_END_TRY();
if (sqlErrorOccurred)  PG_RE_THROW();if (errorOccurred)  ereport(ERROR, "report R error here");

(The ereport will trigger only for errors originating in R, not for
PG errors propagated out, which exit via the RE_THROW.)

However I wonder whether either of these really work.  What happens
inside R's "error()" routine, exactly?  A longjmp?  It seems like this
structure is relying on the stack not to get clobbered between elog.c's
longjmp and R's.  Which would usually work, except when you happened to
get a signal during those few instructions...

It seems like what you really need is a TRY inside each of the functions
you offer as callbacks from R to PG.  These would catch errors, return
them as failures to the R level, which would in turn fail out to the
tryEval call, and from there you could RE_THROW the original error
(which will still be patiently waiting in elog.c).
        regards, tom lane


pgsql-hackers by date:

Previous
From: "Merlin Moncure"
Date:
Subject: win32 crash in initdb
Next
From: Tom Lane
Date:
Subject: Re: try/catch macros for Postgres backend