Re: Error handling in plperl and pltcl

From: Jan Wieck <JanWieck(at)Yahoo(dot)com>
To: Brett Schwarz <brett_schwarz(at)Yahoo(dot)com>
Cc: Richard Huxton <dev(at)archonet(dot)com>, Thomas Hallgren <thhal(at)mailblocks(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, James William Pye <flaw(at)rhid(dot)com>, Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Error handling in plperl and pltcl
Date: 2004-12-02 04:25:59
Message-ID: 41AE9957.4070505@Yahoo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 12/1/2004 1:35 PM, Brett Schwarz wrote:

> --- Jan Wieck <JanWieck(at)Yahoo(dot)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(at)Yahoo(dot)com #

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Bruce Momjian 2004-12-02 04:40:28 Re: Postresql 8.0 Beta 3 - SELECT ... FOR UPDATE
Previous Message Michael Fuhr 2004-12-02 04:10:29 Re: New compile warnings for inheritance