Tom Lane wrote:
> In service of the refactoring of error handling that I was talking about
> a few days ago, I'm finding that there are several places that really
> ought to catch longjmps and clean up after themselves, instead of
> expecting that whatever mess they've made will be cleaned up for them
> when control gets back to PostgresMain().
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:
8<-------------------- /* * trap elog/ereport so we can let R finish up gracefully * and generate the error once
weexit the interpreter */ memcpy(&save_restart, &Warn_restart, sizeof(save_restart)); if (sigsetjmp(Warn_restart,
1)!= 0) { InError = false; memcpy(&Warn_restart, &save_restart, sizeof(Warn_restart)); error("%s", "error
executingSQL statement"); }
[...(execute query via SPI)...]
8<--------------------
The error() call throws the R intepreter error directly, so that on exit
from the R function call I do this:
8<-------------------- ans = R_tryEval(call, R_GlobalEnv, &errorOccurred);
if(errorOccurred) { ereport(ERROR,...
8<--------------------
> Does anyone have a problem with this macro syntax? The try/catch names
> are stolen from Java, so I'm figuring they won't terribly surprise any
> modern programmer, but I'm open to different names if anyone has a
> better idea.
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. Or am I just doing
something wrong here (it seems to work for all of the test cases I could
think of)?
Joe