Re: RfD: more powerful "any" types

From: Merlin Moncure <mmoncure(at)gmail(dot)com>
To: Alvaro Herrera <alvherre(at)commandprompt(dot)com>
Cc: Pg Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: RfD: more powerful "any" types
Date: 2009-09-08 17:19:36
Message-ID: b42b73150909081019h331e4ed9i796debd26b3d94a7@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Tue, Sep 8, 2009 at 12:12 PM, Alvaro
Herrera<alvherre(at)commandprompt(dot)com> wrote:
> Hi,
>
> I'm seeking more powerful "any" pseudotypes.  In particular, consider a
> function
>
> foo(type1, type2) returns type3
>
> where type1 and type2 can be both any element type, but not necessarily
> both of the same type.  Currently this cannot be made to work: you could
> try to write the function this way:
>
> foo(anyelement, anyelement) returns anyelement
>
> but this will force them to be both of the same type, which is not what
> we want.  In my opinion this is a missing feature of our type system.
>
> One seemingly trivial idea would be to have anyelement2, anyelement3,
> and so on.  This is not a very good solution, because we'd have to fill
> the catalogs with a large bunch of new pseudotypes, and the code with a
> bunch of hardcoded tests -- and there are already 27 cases of
> ANYELEMENTOID in our code.
>
>
> For a practical example, I am trying to write a function that returns
> how many NULL arguments it has (this is useful in table CHECK
> constraints).  One simple idea is to use type "unknown":
>
> CREATE FUNCTION a (unknown, unknown, unknown) RETURNS INT LANGUAGE plpgsql AS $$
> DECLARE
>   count int = 0;
> BEGIN
>   IF $1 IS NULL THEN count = count + 1; END IF;
>   IF $2 IS NULL THEN count = count + 1; END IF;
>   if $3 IS NULL THEN count = count + 1; END IF;
>   RETURN count;
> END $$;
>
> The problem is that it doesn't work.  This trivial query does:
>
> alvherre=# select a(null, '2', null);
>  a
> ---
>  2
> (1 fila)
>
> But this one does not:
>
> alvherre=# select a(null, 2, null);
> ERROR:  function a(unknown, integer, unknown) does not exist
>
> and you cannot cast the integer:
> alvherre=# select a(null, 2::unknown, null);
> ERROR:  cannot cast type integer to unknown
>
>
> Before I spend time trying to figure out how this works,
> 1. is there agreement that this is a problem and needs fixed, and
> 2. does anybody have an idea how to attack it?

Since you can do all these things and more in C functions, this
becomes a right tool/wrong tool problem? plpgsql would be fairly
hopeless without some reflection capabilities that we don't currently
have...especially if you consider variadic functions which would be
hard to reconcile with any behavior changes.

I think if you continue going down this road you would end up with a
type system along the lines with c++ templates...so you could do:
DECLARE
foo arg1%type;
etc

And maybe have unique generated plans for each unique set of supplied
input types.

merlin

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message David E. Wheeler 2009-09-08 17:23:43 Re: RfD: more powerful "any" types
Previous Message Tom Lane 2009-09-08 17:15:59 Re: RfD: more powerful "any" types