Re: Error handling in plperl and pltcl
От | Jan Wieck |
---|---|
Тема | Re: Error handling in plperl and pltcl |
Дата | |
Msg-id | 41AE9957.4070505@Yahoo.com обсуждение исходный текст |
Ответ на | Re: Error handling in plperl and pltcl (Brett Schwarz <brett_schwarz@yahoo.com>) |
Ответы |
Re: Error handling in plperl and pltcl
(Thomas Hallgren <thhal@mailblocks.com>)
|
Список | pgsql-hackers |
On 12/1/2004 1:35 PM, Brett Schwarz wrote: > --- Jan Wieck <JanWieck@Yahoo.com> wrote: > >> On 12/1/2004 9:23 AM, Jan Wieck wrote: >> >> > On 12/1/2004 4:27 AM, Richard Huxton wrote: >> > >> >> Thomas Hallgren wrote: >> >>> Richard Huxton wrote: >> >>> >> >>>> Can I make some counter-proposals? >> >>>> >> >>>> 1. Wrap each function body/call (same thing >> here afaict) in a >> >>>> sub-transaction. An exception can be caught >> within that function, and >> >>>> all the spi in that function is then rolled >> back. This is rubbish, but >> >>>> at least it's predictable and allows you to >> write to a log table and >> >>>> throw another exception. >> >>> >> >>> >> >>> This will be even worse since it will impose the >> subtransaction overhead >> >>> on everything, even functions that never do any >> database access. Perhaps >> >>> this approach would be feasible if imposed on >> volatile functions only, >> >>> but then again, the volatility of a function >> cannot be trusted since we >> >>> have no way of defining a "stable but with side >> effects" type. >> >> >> >> Actually, I was thinking of setting a flag and >> then on the first SPI >> >> call start the subtrans. >> >> >> >>>> 2. For pl/tcl introduce a pgtry { } catch { } >> which just starts a >> >>>> sub-transaction and does standard try/catch. I >> don't use TCL, but from >> >>>> the little I know this should be >> straightforward. >> >>> >> >>> >> >>> If you know how to use special constructs like >> this, what's wrong with >> >>> actually using savepoints verbatim? I.e. >> >>> >> >>> INSERT 1 >> >>> INSERT 2 >> >>> SAVEPOINT foo >> >>> try { >> >>> INSERT 3 >> >>> INSERT 4 >> >>> RELEASE foo >> >>> } >> >>> catch WHATEVER { >> >>> ROLLBACK TO foo >> >>> INSERT 5 >> >>> INSERT 6 >> >>> } >> >>> >> >>> IMHO a very clean, sensible, and easily >> understood approach that doesn't >> >>> clobber the language. >> >> >> >> But is the problem not that forgetting to use >> SAVEPOINT can get us in >> >> trouble with clearing up after an exception? >> That's the main thrust of >> >> Tom's per-statement stuff AFAICT. And again, >> you're not going to see the >> >> problem until an exception is thrown. >> > >> > I think the following would a) be a drop in >> replacement without any side >> > effects or performance impact for PL/Tcl functions >> not using "catch" and >> > b) give "catch" a sensible and correct behaviour. >> > >> > One can _replace_ the Tcl catch command with his >> own C function. This >> > can be done during the interpreter initialization >> when loading the >> > PL/Tcl module. The new catch would >> > >> > push a status NEED_SUBTRANS onto a stack >> > call Tcl_Eval() for the first command >> argument >> > if TCL_ERROR { >> > pop status from stack >> > if popped status == HAVE_SUBTRANS { >> > rollback subtransaction >> > } >> > if a second argument exists { >> > store interpreter result in variable >> > } >> > return TCL_ERROR >> >> er ... no ... must return a true boolean with TCL_OK >> here >> >> > } >> > pop status from stack >> > if popped status == HAVE_SUBTRANS { >> > commit subtransaction >> > } >> > >> > return result code from Tcl_Eval() >> >> and here it must put a false boolean into the Tcl >> result ... not 100% >> sure about the result code. Must check if it's >> possible to return or >> break from inside a catch block ... if not, then >> catch allways turns the >> internal result code into TCL_OK. Anyhow, you get >> the idea. >> > > Yes, you can have break, return in a catch > statement...it would return the exception code for > that statement (i.e. TCL_BREAK, TCL_RETURN). Yeah ... little tests are nice :-) catch allways returns the numeric Tcl result status, with TCL_OK being 0, TCL_ERROR being 1 and so on. > > I like this proposal, just as long as it behaves > exactly like Tcl's catch when there is no SPI function > call. That's what I intended, plus that the catch-nesting automatically represents the subtransaction nesting. I can't really see any reason why those two should not be bound together. Does anybody? Jan -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #================================================== JanWieck@Yahoo.com #
В списке pgsql-hackers по дате отправления: