Reputation: 9365
I'm trying to materialize the content of a table into a multidimensional array in PL/PGSQL.
(Just for those who are wondering what the 'neighbors' are: The tables wnode and wedge define a graph with nodes wnode
and edges wedge
. Now I want to store the neighbors of a node v in an array contained in neighbors[v]
).
This is what I've done so far:
DECLARE
neighbors INTEGER[][];
v INTEGER;
BEGIN
FOR v IN SELECT n_id FROM wnode LOOP
SELECT ARRAY ( SELECT n2_id FROM wedge WHERE n1_id=v) INTO neighbors[v];
END LOOP;
RETURN neighbors;
The preceding code fails due to a syntax error:
ROW 7: ...( SELECT n2_id FROM wedge WHERE n1_id=v) INTO neighbors[v];
^
The next thing I tried was introducing a backing variable tmp
:
DECLARE
neighbors INTEGER[][];
v INTEGER;
tmp INTEGER[];
BEGIN
FOR v IN SELECT n_id FROM wnode LOOP
SELECT ARRAY ( SELECT n2_id FROM wedge WHERE n1_id=v) INTO tmp;
neighbors[v] := tmp;
END LOOP;
RETURN neighbors;
END
I got this runtime error:
ERROR: invalid input syntax for integer: »{140,153,290,360,393}«
I also tried using SELECT array_append(neighbors, tmp) INTO neighbors;
without any success.
I'm out of ideas right now. What I'd try next is iterate through tmp
and assign each value neighbors[v][i] := tmp[i];
... not really elegant.
I'd like to know how I can fill my multidimensional array in a more elegant way? (Maybe it is possible by using a single SQL-Query only?).
Thanks for your help. :-)
EDIT: Schema
Upvotes: 2
Views: 1712
Reputation: 658747
This can probably be solved rather easily with the aggregate function outlined under this related question:
Selecting data into a Postgres array
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
,STYPE = anyarray
,INITCOND = '{}'
);
Guess (since table definitions are missing):
SELECT INTO neighbors
array_agg_mult(ARRAY[e_arr]) AS mult_arr
FROM (
SELECT array_agg(n2_id) AS e_arr
FROM wedge
GROUP BY n1_id
ORDER BY n1_id
) e;
You have to add an array-layer to make it a 2d-array.
Note that all 1D-arrays have to share the same length, or the query will error out.
->sqlfiddle to demonstrate both.
Upvotes: 1