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

BUG #13053: type names pollute function name space

From
dwayne.towell@gmail.com
Date:
The following bug has been logged on the website:

Bug reference:      13053
Logged by:          Dwayne Towell
Email address:      dwayne.towell@gmail.com
PostgreSQL version: 9.2.10
Operating system:   CentOS
Description:

The following:

CREATE TYPE x AS (id int);
CREATE FUNCTION _x(text) RETURNS SETOF x AS $$ SELECT 1 WHERE $1='hi'; $$
LANGUAGE SQL;
SELECT _x('hi');

produces:

ERROR:  array value must start with "{" or dimension information
LINE 1: SELECT _x('hi');

Which seems wrong. Creating a type named 'x' should not preempt my function
by finding an auto created(?) conversion(?) function.

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

From
"David G. Johnston"
Date:
On Tue, Apr 14, 2015 at 2:24 PM, <dwayne.towell@gmail.com> wrote:

> The following bug has been logged on the website:
>
> Bug reference:      13053
> Logged by:          Dwayne Towell
> Email address:      dwayne.towell@gmail.com
> PostgreSQL version: 9.2.10
> Operating system:   CentOS
> Description:
>
> The following:
>
> =E2=80=8B=E2=80=8B
> CREATE TYPE x AS (id int);
> CREATE FUNCTION _x(text) RETURNS SETOF x AS $$ SELECT 1 WHERE $1=3D'hi'; =
$$
> LANGUAGE SQL;
> SELECT _x('hi');
>
> produces:
>
> ERROR:  array value must start with "{" or dimension information
> LINE 1: SELECT _x('hi');
>
> Which seems wrong. Creating a type named 'x' should not preempt my functi=
on
> by finding an auto created(?) conversion(?) function.
>

=E2=80=8BTo be more explicit about what is happening here=E2=80=8B:

It is finding the auto-magically created type "array x" aka: "x[]=E2=80=8B"=
.  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.

I'll admit it seems odd but I'd chalk this up to system oddity and move
on.  What is the solution you are looking for anyway?

I'm sure there are more surprises relating to types and functions since
functions are used to manipulate types - and as described above some
synatic sugar is involved as well - and maybe they could be better
documented...but I'm not see where preventing the creation of either the
function or the type (whichever is created last) is a viable solution and
I'm not seeing that the current rule of using the implied type cast
function first is necessarily wrong.

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.

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"...?

Not that I could fix this even if I wanted to but the effort compared to
the number of complaints is not favorable to any change being forthcoming.
That includes documentation though that is more likely if someone even puts
forth a rough suggestion for what such an improvement would look like.

David J.

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

From
"Dwayne Towell"
Date:
I figured it had something to do with array types, given the error, but =
still feel like creating the function, when it cannot be called, is an =
error. I would appreciate getting an error similar to the one you =
described instead of one later when attempting to call the function =
since I would have saved me a couple of hours of debugging. I would =
appreciate it if the documentation contained some hint that =
type-conversion functions were automatically created by prepending an =
underscore. (I don=E2=80=99t know how I would have found that nugget =
without a better error message but still feel it is missing.)

=20

I also tried the quoted-identifier trick and was equally surprised it =
didn=E2=80=99t work and then on reflection relieved that it =
didn=E2=80=99t either.

=20

We have solved the problem by changing our naming convention, given the =
usual momentum on projects like this I don=E2=80=99t expect it to be =
changed, but better documentation and an better error would be =
appreciated.

=20

From: David G. Johnston [mailto:david.g.johnston@gmail.com]=20
Sent: Tuesday, April 14, 2015 3:55 PM
To: dwayne.towell@gmail.com
Cc: pgsql-bugs@postgresql.org
Subject: Re: [BUGS] BUG #13053: type names pollute function name space

=20

On Tue, Apr 14, 2015 at 2:24 PM, <dwayne.towell@gmail.com =
<mailto:dwayne.towell@gmail.com> > wrote:

The following bug has been logged on the website:

Bug reference:      13053
Logged by:          Dwayne Towell
Email address:      dwayne.towell@gmail.com =
<mailto:dwayne.towell@gmail.com>=20
PostgreSQL version: 9.2.10
Operating system:   CentOS
Description:

The following:

=E2=80=8B=E2=80=8B

CREATE TYPE x AS (id int);
CREATE FUNCTION _x(text) RETURNS SETOF x AS $$ SELECT 1 WHERE $1=3D'hi'; =
$$
LANGUAGE SQL;
SELECT _x('hi');

produces:

ERROR:  array value must start with "{" or dimension information
LINE 1: SELECT _x('hi');

Which seems wrong. Creating a type named 'x' should not preempt my =
function
by finding an auto created(?) conversion(?) function.

=20

=E2=80=8BTo be more explicit about what is happening here=E2=80=8B:

=20

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

=20

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.

=20

I'll admit it seems odd but I'd chalk this up to system oddity and move =
on.  What is the solution you are looking for anyway?

=20

I'm sure there are more surprises relating to types and functions since =
functions are used to manipulate types - and as described above some =
synatic sugar is involved as well - and maybe they could be better =
documented...but I'm not see where preventing the creation of either the =
function or the type (whichever is created last) is a viable solution =
and I'm not seeing that the current rule of using the implied type cast =
function first is necessarily wrong.

=20

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.

=20

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"...?

=20

Not that I could fix this even if I wanted to but the effort compared to =
the number of complaints is not favorable to any change being =
forthcoming.  That includes documentation though that is more likely if =
someone even puts forth a rough suggestion for what such an improvement =
would look like.

=20

David J.

=20

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

From
Tom Lane
Date:
"David G. Johnston" <david.g.johnston@gmail.com> writes:
> On Tue, Apr 14, 2015 at 2:24 PM, <dwayne.towell@gmail.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