Re: How do I create an array?

From: Joe Conway <mail(at)joeconway(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Greg Stark <gsstark(at)mit(dot)edu>, pgsql-general(at)postgresql(dot)org
Subject: Re: How do I create an array?
Date: 2003-02-06 16:20:50
Message-ID: 3E428B62.4030409@joeconway.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Tom Lane wrote:
> Joe Conway <mail(at)joeconway(dot)com> writes:
>>CREATE OR REPLACE FUNCTION array (float8, float8) RETURNS float8[] AS
>>'$libdir/plr','array' LANGUAGE 'C' WITH (isstrict);
>
> Yeah, that's what I was referring to by a "bespoke function". You'd
> need one for every datatype; plus an entry in pg_proc for every number
> of arguments you want to support (and it won't scale past MAX_FUNC_ARGS).
> Doesn't seem like the avenue to a general solution.

Agreed. That's why I never sent it in to patches. Of course, I also wrote:

CREATE OR REPLACE FUNCTION array_push (_float8, float8)
RETURNS float8[]
AS '$libdir/plr','array_push'
LANGUAGE 'C';

Still not a general solution because of the need-one-for-each-datatype issue,
but it at least allows plpgsql to build an array, e.g.:

create or replace function array_accum(_float8, float8) returns float8[] as '
DECLARE
inputarr alias for $1;
inputval alias for $2;
BEGIN
if inputarr is null then
return array(inputval);
else
return array_push(inputarr,inputval);
end if;
END;
' language 'plpgsql';

BTW, while playing with this I noted that creating the function like:
create or replace function array_accum(float8[], float8)
didn't seem to work. Is that a known issue? I also noticed you fixed a similar
issue in that last day or two, so maybe its no longer a problem. (checks --
yup, looks like it's fixed now).

It seems like you should be able to define the function:
CREATE OR REPLACE FUNCTION array (any)
RETURNS anyarray
AS '$libdir/plr','array'
LANGUAGE 'C' WITH (isstrict);

since return value carries along its own element type.

> This morning I was musing about overloading the CAST syntax to allow
> array construction, along the lines of
>
> CAST((x,y,z+2) AS float8[])
>
> Perhaps multidimensional arrays could be done like this
>
> CAST(((a11,a12,a13), (a21,a22,a23)) AS float8[])
>
> But there are other ways you could imagine doing it, too.

From SQL99
<array value expression> ::= <array value constructor>
| <array concatenation>
| <value expression primary>

<array concatenation> ::= <array value expression 1>
<concatenation operator>
<array value expression 2>
<array value expression 1> ::= <array value expression>
<array value expression 2> ::= <array value expression>

<array value constructor> ::= <array value list constructor>
<array value list constructor> ::= ARRAY <left bracket or trigraph>
<array element list>
<right bracket or trigraph>
<array element list> ::= <array element> [ { <comma> <array element> }... ]
<array element> ::= <value expression>

So if I read that correctly, we'd want:

ARRAY [x, y, z+2]

and in section 6.4 SQL99 indicates that the array datatype should be derived
from the datatype of its first element (again, not sure I'm reading the spec
correctly):

6.4 <contextually typed value specification>
1) The declared type DT of an <empty specification> ES is ET ARRAY[0], where
the element type ET is determined by the context in which ES appears. ES is
effectively replaced by CAST ( ES AS DT ).

Does that make sense?

Joe

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Andrew Sullivan 2003-02-06 16:23:11 Re: password() function?
Previous Message Robert Treat 2003-02-06 16:17:48 Re: password() function?