Joe Conway <[EMAIL PROTECTED]> 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 ---------------------------(end of broadcast)--------------------------- TIP 2: you can get off all lists at once with the unregister command (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])