On Fri, Sep 24, 2010 at 11:15 PM, Robert Haas <robertmh...@gmail.com> wrote:

> On Fri, Sep 24, 2010 at 3:41 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:
> > Robert Haas <robertmh...@gmail.com> writes:
> >> On Tue, Sep 21, 2010 at 7:05 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:
> >>> There are many rules that you could possibly make for type input
> >>> functions.  But "you cannot throw an error" is not one of them ---
> >>> or at least, not one that you can usefully expect to be followed
> >>> for anything more than trivial straightline code.
> >
> >> OK.  This is one of the things I don't understand.  Why does throwing
> >> an error imply that we need to abort the current transaction?  Why
> >> can't we just catch the longjmp() and trundle onwards?  Obviously,
> >> that's unsafe if a pretty wide variety of cases, but if you're just
> >> scrutinizing the input string (even with a little bit of read-only
> >> database access) it's not obvious to me what can go wrong.
> >
> > The problem is to know that "all you did" was scrutinize the input
> > string.  If it's simple straightline code (even with some C library
> > calls) then you can know that, but then you can write such code without
> > including any elog(ERROR) in it in the first place.  If you are trapping
> > longjmps then what you'd need to assert is that no error thrown from
> > anywhere in any of the code reachable from that place represents a
> > problem that requires transaction abort to clean up after.  This gets
> > unmaintainable remarkably quickly, especially if you invoke anything
> > as complicated as database access.  And then there are asynchronous
> > error reasons (query cancel) which you shouldn't trap in any case.
>
> Hmm.  So the problem is that we don't want to accidentally catch an
> error that isn't actually safe to catch.  We could probably mitigate
> this problem to a considerable degree by throwing data validation
> errors using some special flag that say "this is a recoverable error".
>  And if that flag isn't set then we abort the whole transaction, but
> if it is then we continue on.  It's still possible for the person
> writing the typinput function to set that flag when they should not,
> but at least it's less likely to happen by accident.  Another
> alternative would be to create some kind of explicit way for the
> function to RETURN an error instead of throwing it.
>
> But neither of these things is totally bullet-proof, because you could
> still do something that requires clean-up and then lie about it.  To
> protect against that, you'd presumably need to set some kind of a flag
> whenever, say, a heap tuple gets modified, and then you could assert
> said flag false.  What, other than writing to the database, requires
> subtransaction cleanup?
>
>
Andrew suggested upthread:

<snip>
   test_date := date_in(textout(some_text));

In plpgsql you'd put that inside a begin/exception/end block that traps
SQLSTATE '22000' which is the class covering data exceptions.
  </snip>


    In context of COPY, can we check for this SQLSTATE in PG_CATCH() and
avoid PG_RE_THROW(). This would require that all type input functions call
errcode() with proper MAKE_SQLSTATE() as part of ereport()/elog().

Regards,
-- 
gurjeet.singh
@ EnterpriseDB - The Enterprise Postgres Company
http://www.EnterpriseDB.com

singh.gurj...@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet

Mail sent from my BlackLaptop device

Reply via email to