Noah Misch <n...@leadboat.com> writes:
> On Mon, May 09, 2011 at 11:32:28PM -0400, Tom Lane wrote:
>> So we basically had three alternatives to make it better:
>>      * downcast to the array type, which would possibly silently
>>        break applications that were relying on the function result
>>        being considered of the domain type
>>      * re-apply domain checks on the function result, which would be
>>        a performance hit and possibly again result in unobvious
>>        breakage
>>      * explicitly break it by throwing a parse error until you
>>        downcast (and then upcast the function result if you want)
>> I realize that #3 is a bit unpleasant, but are either of the other two
>> better?  At least #3 shows you where you need to check for problems.

> Though I've never used a domain over an array type, I'd strongly prefer #2.

Hmm.  I hadn't seriously considered that alternative, but we could go in
that direction.  Logically, what this would probably imply is inserting
CastToDomain whenever the result of a polymorphic function is deemed to
be of a domain type, whether the base type is array or not.

The reason I hadn't taken it very seriously is that I don't think it's
actually going to end up being consistent.  If we don't do #1 (downcast
polymorphic arguments to a base type), but consider the arguments passed
to the function to be of the domain type, then really we have to expect
the polymorphic function to enforce domain constraints internally; we
cannot fix it with something as localized as having the function call
parser stick a CastToDomain on top.  Here's a possibly rather silly
example:

        create function negate(anyelement) returns anyelement as
        $$ select - $1 $$ language sql;

        create domain pos as int check (value > 0);

        select negate(42::pos);

This negate() function will work for any type that has a unary minus
operator.  But the result of the unary minus operation cannot sanely be
considered to be of this domain type.  In this simplified example you
might feel it doesn't matter, since with an external CastToDomain we'd
throw error anyway a moment later, as soon as control comes back from
the function.  But what if the function does further operations with the
value, such as passing it to another polymorphic function?

So really, if you go down this path, you end up concluding that PLs
supporting polymorphic arguments had better be prepared to enforce
domain constraints all the way through, and thus there should be no need
for an external CastToDomain --- what comes back from the function ought
to be checked already.  Unfortunately, even if the PLs do that (SQL
functions might get it right, but I'm not real sure whether plpgsql is
water-tight on this, and I don't trust the other PLs for it at all),
there's no way that built-in polymorphic functions like array_append are
going to.

So on the whole, #2 looks like an implementation quagmire to me: it's
not clear what to check, or where, or how you know when you're done.
I'm not willing to volunteer my own time to make it work that way.
If somebody else who uses domains a lot wants to step up and take
responsibility, go for it.

                        regards, tom lane

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to