From: | Merlin Moncure <mmoncure(at)gmail(dot)com> |
---|---|
To: | Gerhard Heift <ml-postgresql-20081012-3518(at)gheift(dot)de>, PostgreSQL general <pgsql-general(at)postgresql(dot)org>, Osvaldo Kussama <osvaldo(dot)kussama(at)gmail(dot)com> |
Subject: | Re: change array dimension |
Date: | 2010-07-02 13:54:02 |
Message-ID: | AANLkTimwduGWSkTCRmJO9DKzkhofllh3p8-SByr13GLg@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On Thu, Jul 1, 2010 at 7:32 PM, Gerhard Heift
<ml-postgresql-20081012-3518(at)gheift(dot)de> wrote:
> Hello,
>
> is it possible to change the dimension of an array? I am looking for something
> like this:
>
> SELECT change_array_dims('[1:2][1:2]', '{1,2,3,4}'::int[]);
> change_array_dims
> -------------------
> {{1,2},{3,4}}
>
> and the other way around:
>
> SELECT change_array_dims('[1:4]', '{{1,2},{3,4}}'::int[]);
> change_array_dims
> -------------------
> {1,2,3,4}
>
> Does such a function exist?
>
> Thanks,
> Gerhard
It can be done, but your inner slices must all compute to the same
length. things can also get confusing real fast if we are trying to
stack into arrays of dimensions > 2:
create or replace function array_safecat(p1 anyarray, p2 anyarray)
returns anyarray as
$$
select case when $1::text = '{}' then array[$2] else array_cat($1, $2) end;
$$ language sql immutable;
create aggregate array_stack(anyarray)
(
sfunc = array_safecat,
stype = anyarray,
initcond = '{}'
);
create or replace function change_array_dims(
_slice_lbounds int[],
_slice_len int,
_array anyarray) returns anyarray as
$$
select array_stack(a) from
(
select $3[$1[v]:$1[v] + ($2 - 1)] as a
from generate_series(1, array_upper($1, 1)) v
) q;
$$ language sql immutable;
postgres=# select change_array_dims(array[1,2,3], 2, array[1,2,3,4]);
change_array_dims
---------------------
{{1,2},{2,3},{3,4}}
(1 row)
postgres=# select change_array_dims(array[1,3], 2, array[1,2,3,4]);
change_array_dims
-------------------
{{1,2},{3,4}}
(1 row)
Osvaldo: this is a slight improvement on your 'array_cat1': the text
is on the constant instead of the input array so you don't have to
make different versions for each type:
postgres=# select change_array_dims(array[1,2], 3,
array['w','x','y','z']::text[]);
change_array_dims
-------------------
{{w,x,y},{x,y,z}}
(1 row)
restacking arrays is easy:
create or replace function restack(_array anyarray) returns anyarray as
$$
select array(select unnest($1));
$$ language sql immutable;
postgres=# select restack(array[array['a','b','c','d']::text[],
array['w','x','y','z']::text[]]);
restack
-------------------
{a,b,c,d,w,x,y,z}
(1 row)
merlin
From | Date | Subject | |
---|---|---|---|
Next Message | Scott Marlowe | 2010-07-02 13:59:46 | Re: Postgresql partitioning - single hot table or distributed |
Previous Message | Geoffrey | 2010-07-02 13:46:58 | Re: pgpool-II (max_pool and num_init_children) |