Re: BUG #13053: type names pollute function name space

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>
Cc: dwayne(dot)towell(at)gmail(dot)com, "pgsql-bugs(at)postgresql(dot)org" <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: BUG #13053: type names pollute function name space
Date: 2015-04-15 12:01:23
Message-ID: 3402.1429099283@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

"David G. Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com> writes:
> On Tue, Apr 14, 2015 at 2:24 PM, <dwayne(dot)towell(at)gmail(dot)com> wrote:
>> CREATE TYPE x AS (id int);
>> CREATE FUNCTION _x(text) RETURNS SETOF x AS $$ SELECT 1 WHERE $1='hi'; $$
>> LANGUAGE SQL;
>> SELECT _x('hi');
>> ERROR: array value must start with "{" or dimension information
>> LINE 1: SELECT _x('hi');

> It is finding the auto-magically created type "array x" aka: "x[]". For
> reasons unknown to myself the underlying representation type is named "_x".

> Then, since "type 'literal'" and "type('literal') are equivalent to
> "'literal'::type", SELECT _x('literal') becomes ambiguous and its (_x)
> treatment as a type precedes its treatment as a function name.

Yeah. See the documentation at
http://www.postgresql.org/docs/9.2/static/typeconv-func.html
as well as the further commentary on the CREATE CAST reference page.

> I would have thought that maybe you could access the original function
> using double-quotes: SELECT "_x"('hi'); but that appears to be
> incorrect...and not obviously useful even if it worked.

No, the way to think about this is that it's a overloaded-function
problem. You can force the correct function to be called if the arguments
are of exactly the expected types, which an unknown-type literal isn't:

regression=# SELECT _x('hi'::text);
_x
-----
(1)
(1 row)

That works because the exact-match case precedes the cast-function case
in the function resolution rules.

> FWIW in the example provided I would prefer to have the CREATE FUNCTION
> call fail with a "function already exists" error - though I do not believe
> that is strictly correct. Maybe "unsupported function signature - matching
> array of type x already exists"...?

That won't happen because there is not in fact any conflicting function.
In the first place, the cast function was never really created (see the
footnote at the bottom of the doc page I cited); in the second place,
if it had been created it would likely be considered to have "unknown"
as the input type.

A more plausible way to eliminate the conflict would be to get rid of the
casts-as-function-calls notation; but that would break an awful lot of
existing client code, so I think the odds of us doing that are about nil.

regards, tom lane

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message adam.smith 2015-04-15 12:21:37 BUG #13060: no pg_update in /usr/pgsql-9.4/bin
Previous Message Dwayne Towell 2015-04-14 23:04:54 Re: BUG #13053: type names pollute function name space