Re: Error handling in plperl and pltcl

From: Jan Wieck <JanWieck(at)Yahoo(dot)com>
To: Thomas Hallgren <thhal(at)mailblocks(dot)com>
Cc: Brett Schwarz <brett_schwarz(at)Yahoo(dot)com>, Richard Huxton <dev(at)archonet(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-03 16:28:16
Message-ID: 41B09420.7030509@Yahoo.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 12/2/2004 3:18 AM, Thomas Hallgren wrote:

> Jan,
>
>> ... 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?
>
> That depends on what you mean. As a stop-gap solution, cerntanly. But in
> the long run, I still think that savepoints and exception handling
> should be kept separate. Consider the following two examples:
>
> savepoint a
> spi calls
> savepoint b
> spi calls
> savepoint c
> spi calls
>
> switch(some test)
> {
> case 1:
> rollback b;
> commit a;
> break;
> case 2:
> rollback c;
> commit a;
> break;
> case 3:
> rollback a;
> break;
> default:
> commit a;
> }

I don't know, but doing a lot of work only to later decide to throw it
away doesn't strike me as a good programming style. Some test should be
done before performing the work.

>
> or nested try/catch where the catch doesn't access the database:

There is no "try" in Tcl.

The syntax is

catch { block-of-commands } [variable-name]

Catch returns a numeric result, which is 0 if there was no exception
thrown inside of the block-of-commands. The interpreter result, which
would be the exceptions error message in cleartext, is assigned to the
optional variable specified. Thus, your code usually looks like this:

if {[catch {statements-that-might-fail} err]} {
on-error-action
} else {
on-success-action
}

>
> foo()
> {
> try
> {
> spi calls;
> }
> catch
> {
> set some status;
> re-throw;
> }
> }
>
> and some other place in the code:
>
> savepoint a
> try
> {
> spi calls;
> for(i = 0; i < 100; ++i)
> foo();
> commit a;
> }
> catch
> {
> rollback a;
> }
>
> If "normal" savepoint hanling is disabled here in favor of your
> suggestion, you will get 101 subtransations although only 1 is relevant.

Your example shows where leaving the burdon on the programmer can
improve performance. But change it to this:

foo {} {
spi-calls;

if {[catch {spi-call} err]} {
return "boo: $err"
}
return "hooray"
}

This function never throws any exception. And any normal Tcl programmer
would expect that the spi-calls done before the catch will either abort
the function on exception, or if they succeed, they get committed. What
you mean with "normal" savepoint handling in fact means that we don't
change catch at all but just expose the savepoint feature on the Tcl level.

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 Alvaro Herrera 2004-12-03 16:35:56 pg_restore --help
Previous Message Tom Lane 2004-12-03 16:26:12 Re: Adding a suffix array index