Thread: Oddities with ANYARRAY

Oddities with ANYARRAY

From
Decibel!
Date:
David Fetter and I were just looking at something on IRC...

decibel=3D# select most_common_vals[1] from pg_stats where tablename=3D'pg_=
depend' and attname=3D'classid';
ERROR:  cannot subscript type anyarray because it is not an array
decibel=3D# select most_common_freqs[1] from pg_stats where tablename=3D'pg=
_depend' and attname=3D'classid';
 most_common_freqs=20
-------------------
             0.566
(1 row)

ISTM you'd want to be able to reference an individual element of an
ANYARRAY... but this gets even more odd...

decibel=3D# CREATE OR REPLACE FUNCTION array_to_set(anyarray) RETURNS SETOF=
 anyelement LANGUAGE SQL AS $$
    SELECT $1[i] from generate_series(array_lower($1, 1), array_upper($1, 1=
)) i
$$;
CREATE FUNCTION
decibel=3D# select array_to_set(most_common_vals) from pg_stats where table=
name=3D'pg_depend' and attname=3D'classid';
ERROR:  argument declared "anyarray" is not an array but type anyarray

I expected that not to work, but the error is somewhat interesting...

I didn't expect the following to work:

decibel=3D# select array_to_set(most_common_freqs) from pg_stats where tabl=
ename=3D'pg_depend' and attname=3D'classid';
 array_to_set=20
--------------
        0.566
     0.235667
     0.126333
    0.0343333
         0.02
    0.0163333
  0.000666667
  0.000666667
(8 rows)

decibel=3D#=20

ISTM you should be able to call an anyarray function with an anyarray,
and that you should be able to reference individual elements of an
anyarray...
--=20
Decibel!, aka Jim Nasby                        decibel@decibel.org
EnterpriseDB      http://enterprisedb.com      512.569.9461 (cell)

Re: Oddities with ANYARRAY

From
Tom Lane
Date:
Decibel! <decibel@decibel.org> writes:
> ISTM you'd want to be able to reference an individual element of an
> ANYARRAY...

And what type would the result have?

pg_statistic is definitely pushing the boundaries of the type system
by having an anyarray column.  We don't allow that in normal user
tables...

            regards, tom lane

Re: Oddities with ANYARRAY

From
Alvaro Herrera
Date:
Decibel! wrote:
> David Fetter and I were just looking at something on IRC...
>
> decibel=# select most_common_vals[1] from pg_stats where tablename='pg_depend' and attname='classid';
> ERROR:  cannot subscript type anyarray because it is not an array
> decibel=# select most_common_freqs[1] from pg_stats where tablename='pg_depend' and attname='classid';
>  most_common_freqs
> -------------------
>              0.566
> (1 row)

The difference is that most_common_freqs is a real[], which means it
behaves as a regular array (subscript etc).  most_common_vals, on the
other hand, is a quite hackish thing and very unique -- it's the only
column in all the database that has type anyarray.

The reason for most_common_vals being anyarray is that it must be able
to hold an array of any type at all; but the problem is that it is quite
difficult to make it work anywhere else, because normally anyarray types
are resolved to some specific array type early in the life of a query.
In this case it cannot.

In fact, standalone mode has a very particular hack to allow anyarray to
be used as a type in a table, which is there precisely (and only) for
allowing pg_statistic to get created.

> decibel=# CREATE OR REPLACE FUNCTION array_to_set(anyarray) RETURNS SETOF anyelement LANGUAGE SQL AS $$
>     SELECT $1[i] from generate_series(array_lower($1, 1), array_upper($1, 1)) i
> $$;
> CREATE FUNCTION
> decibel=# select array_to_set(most_common_vals) from pg_stats where tablename='pg_depend' and attname='classid';
> ERROR:  argument declared "anyarray" is not an array but type anyarray

Yeah, that error message is weird.

--
Alvaro Herrera                                http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

Re: Oddities with ANYARRAY

From
Gregory Stark
Date:
"Decibel!" <decibel@decibel.org> writes:

> David Fetter and I were just looking at something on IRC...
>
> decibel=# select most_common_vals[1] from pg_stats where tablename='pg_depend' and attname='classid';
> ERROR:  cannot subscript type anyarray because it is not an array
> decibel=# select most_common_freqs[1] from pg_stats where tablename='pg_depend' and attname='classid';
>  most_common_freqs
> -------------------
>              0.566
> (1 row)
>
> ISTM you'd want to be able to reference an individual element of an
> ANYARRAY... but this gets even more odd...

And what type would the result be?

But this is an odd coincidence as I was just looking at this myself to do
those histogram charts I was talking about. The solution I was going to
propose was to allow casting from anyarray to a normal array, then allow
subscripting the normal array.

I would be fine requiring the cast to be to the correct array type with a
run-time error if the type doesn't match. Or it could use the VIAIO cast which
would work as long as the input format matched. So you could always cast to
text[] even if it was an integer[] or something else originally.

--
  Gregory Stark
  EnterpriseDB          http://www.enterprisedb.com

Re: Oddities with ANYARRAY

From
Decibel!
Date:
On Jul 31, 2007, at 11:55 PM, Gregory Stark wrote:
> "Decibel!" <decibel@decibel.org> writes:
>
>> David Fetter and I were just looking at something on IRC...
>>
>> decibel=# select most_common_vals[1] from pg_stats where
>> tablename='pg_depend' and attname='classid';
>> ERROR:  cannot subscript type anyarray because it is not an array
>> decibel=# select most_common_freqs[1] from pg_stats where
>> tablename='pg_depend' and attname='classid';
>>  most_common_freqs
>> -------------------
>>              0.566
>> (1 row)
>>
>> ISTM you'd want to be able to reference an individual element of an
>> ANYARRAY... but this gets even more odd...
>
> And what type would the result be?

ANYELEMENT? I know that'd still have to be casted to something normal
eventually; do we have support for that?

> But this is an odd coincidence as I was just looking at this myself
> to do
> those histogram charts I was talking about. The solution I was
> going to
> propose was to allow casting from anyarray to a normal array, then
> allow
> subscripting the normal array.
>
> I would be fine requiring the cast to be to the correct array type
> with a
> run-time error if the type doesn't match. Or it could use the VIAIO
> cast which
> would work as long as the input format matched. So you could always
> cast to
> text[] even if it was an integer[] or something else originally.

I'd expected that the 'ANY' types had additional information
somewhere that told them what the original data type actually was,
but I guess that's not the case. Maybe it'd be worth adding?
--
Decibel!, aka Jim Nasby                        decibel@decibel.org
EnterpriseDB      http://enterprisedb.com      512.569.9461 (cell)

Re: Oddities with ANYARRAY

From
Gregory Stark
Date:
"Decibel!" <decibel@decibel.org> writes:

> On Jul 31, 2007, at 11:55 PM, Gregory Stark wrote:
>>
>> And what type would the result be?
>
> ANYELEMENT? I know that'd still have to be casted to something normal
> eventually; do we have support for that?

There isn't really any such thing. There isn't really any such thing as
anyarray either, the actual arrays are normal arrays of a real data type.

anyarray and anyelement are things the parser and labels things it doesn't
know better. Normally that's just parameters of polymorphic functions since
you can't define columns of type anyarray normally. pg_statistic is a magic
exception.

> I'd expected that the 'ANY' types had additional information somewhere that told
> them what the original data type actually was,  but I guess that's not the case.
> Maybe it'd be worth adding?

Well arrays do. That's the only reason we can output the arrays from
pg_statistic. So we could cast an anyarray to an array of a specific data
type. The parser would be able to make sense of (histogram_bounds::text[])[1]
since it's obviously a text.

--
  Gregory Stark
  EnterpriseDB          http://www.enterprisedb.com

Re: Oddities with ANYARRAY

From
Decibel!
Date:
On Thu, Aug 02, 2007 at 12:44:02AM +0100, Gregory Stark wrote:
>=20
> "Decibel!" <decibel@decibel.org> writes:
>=20
> > On Jul 31, 2007, at 11:55 PM, Gregory Stark wrote:
> >>
> >> And what type would the result be?
> >
> > ANYELEMENT? I know that'd still have to be casted to something normal
> > eventually; do we have support for that?
>=20
> There isn't really any such thing. There isn't really any such thing as
> anyarray either, the actual arrays are normal arrays of a real data type.
>=20
> anyarray and anyelement are things the parser and labels things it doesn't
> know better. Normally that's just parameters of polymorphic functions sin=
ce
> you can't define columns of type anyarray normally. pg_statistic is a mag=
ic
> exception.
>=20
> > I'd expected that the 'ANY' types had additional information somewhere =
that told
> > them what the original data type actually was,  but I guess that's not =
the case.
> > Maybe it'd be worth adding?
>=20
> Well arrays do. That's the only reason we can output the arrays from
> pg_statistic. So we could cast an anyarray to an array of a specific data
> type. The parser would be able to make sense of (histogram_bounds::text[]=
)[1]
> since it's obviously a text.

So is ANYARRAY actually a 'real' type in the sense that it remembers the
data type that was passed into it? Or is it more like a label like you
said above?

How horrible would it be to add the ability for an anyarray/anyelement
to know what the original data type was? There's certainly times when
having that ability would be extremely useful; right now people just
fudge it by using text instead.
--=20
Decibel!, aka Jim Nasby                        decibel@decibel.org
EnterpriseDB      http://enterprisedb.com      512.569.9461 (cell)