Re: What happened to the is_<type> family of functions proposal?
Gurjeet Singh <singh.gurjeet@gmail.com>
From: Gurjeet Singh <singh.gurjeet@gmail.com>
To: Robert Haas <robertmhaas@gmail.com>
Cc: Tom Lane <tgl@sss.pgh.pa.us>, Greg Stark <gsstark@mit.edu>, Alvaro Herrera <alvherre@commandprompt.com>, "Colin 't Hart" <colinthart@gmail.com>, Andrew Dunstan <andrew@dunslane.net>, pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2010-09-25T08:36:24Z
Lists: pgsql-hackers
On Fri, Sep 24, 2010 at 11:15 PM, Robert Haas <robertmhaas@gmail.com> wrote:
> On Fri, Sep 24, 2010 at 3:41 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> > Robert Haas <robertmhaas@gmail.com> writes:
> >> On Tue, Sep 21, 2010 at 7:05 PM, Tom Lane <tgl@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.gurjeet@{ gmail | yahoo }.com
Twitter/Skype: singh_gurjeet
Mail sent from my BlackLaptop device