So I noticed that postgres (9.0) doesn't like it when you dereference a 2d array with only 1 dimension. Here's a funny example
WITH my_table(arr) AS ( VALUES (ARRAY[[10,11],[20,21]]) )
SELECT arr[2][1] AS good, arr[1] AS bad FROM my_table;
good | bad
------+-----
20 |
(1 row)
As you can see this returns null when you don't specify the second dimension. Ideally I'd like it to return the inner array {10,11}. So to solve this I wrote this function
CREATE OR REPLACE FUNCTION deref_2d(orig_arr numeric[][], inner_arr int)
RETURNS numeric[] AS $$
DECLARE
index int;
len int;
return_arr numeric[];
BEGIN
len := array_upper(orig_arr,2);
FOR index IN 1 .. len LOOP
return_arr[index] := orig_arr[inner_arr][index];
END LOOP;
RETURN return_arr;
END
$$ LANGUAGE plpgsql;
And now I can write:
WITH my_table(arr) AS ( VALUES (ARRAY[[10,11],[20,21]]) )
SELECT deref_2d(arr,1) FROM my_table;
deref_2d
----------
{10,11}
But multiple things about this make me feel uneasy about my solution. Is there a better way to do this?
Consider the full cast of this Western before you write it off:
WITH tbl(arr) AS (SELECT (ARRAY[[10,11],[20,21]]))
SELECT arr[2][1] AS the_good
,arr[1] AS the_bad
,arr[1:1] AS the_ugly -- first slice of 2D-array
,arr[1][1:2] AS the_ugly_twin -- 2D-array with elements 1 & 2 of 1st slice
,ARRAY((SELECT unnest(arr[1:1]))) AS the_righteous -- 1D-array of 1st slice
FROM tbl;
->sqlfiddle with more examples.
Some background in the manual here and here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With