Re: Error handling in plperl and pltcl - Mailing list pgsql-hackers

From Jan Wieck
Subject Re: Error handling in plperl and pltcl
Date
Msg-id 41B09420.7030509@Yahoo.com
Whole thread Raw
In response to Re: Error handling in plperl and pltcl  (Thomas Hallgren <thhal@mailblocks.com>)
Responses Re: Error handling in plperl and pltcl
List 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@Yahoo.com #


pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: Adding a suffix array index
Next
From: Alvaro Herrera
Date:
Subject: Re: pg_restore --help