PostgreSQL 8.2 -- How to get a string representation of any array?

2.9k Views Asked by At

In PostgreSQL8.2, what's the inverse of PostgreSQL's text-to-array conversion?

As we know:

select '{a,b,c}'::text[] as x, '{{0,1},{2,3}}'::int[][] as y;
/*
 *     x    |       y
 * ---------+---------------
 *  {a,b,c} | {{0,1},{2,3}}
 */

Is there a predefined function f(anyarray) or an operator to do the inverse? By "inverse", I mean that applying f(x)::text[] or f(y)::int[][] would bring it back to array form.

The following is a hypothetical example, just to illustrate the point.

select 'x='||f(x) as x_str, 'y'=f(y) as y_str
from (
  select '{a,b,c}'::text[] as x, '{{0,1},{2,3}}'::int[][] as y;
) as a;
/*
 *      x     |        y
 * -----------+-----------------
 *  x={a,b,c} | y={{0,1},{2,3}}
 */

Edit: Unfortunately (and trust me, that's the first thing I had tried before wasting anyone's time here), select x::text doesn't work for me (because I'm stuck with PostgreSQL8.2 --I use Greenplum):

test=> SELECT ('{a,b,c}'::text[])::text;
ERROR:  cannot cast type text[] to text
LINE 1: SELECT ('{a,b,c}'::text[])::text;
                                    ^

Edit #2: Unlike what has been asserted by some, this has nothing to do with Greenplum. It has everything to do with PostgreSQL8.2. I verified that anyarray cannot be cast to text on a vanilla PostgreSQL 8.2.

In fact, the change that makes select ('{a,b,c}'::text[])::text; work was introduced in version 8.3.0, as per the following change log (in the HISTORY file distributed with the source):

 * Create a general mechanism that supports casts to and from the
   standard string types (TEXT, VARCHAR, CHAR) for *every* datatype,
   by invoking the datatype's I/O functions (Tom)
   Previously, such casts were available only for types that had
   specialized function(s) for the purpose. These new casts are
   assignment-only in the to-string direction, explicit-only in the
   other direction, and therefore should create no surprising
   behavior.

In order for me to be 100% certain about this, I just went ahead and compiled from source both pg 8.2.23 and 8.3.0. Indeed, in 8.3.0 it works:

test=# select version();
                                                  version                                                   
------------------------------------------------------------------------------------------------------------
 PostgreSQL 8.3.0 on x86_64-unknown-linux-gnu, compiled by GCC gcc47 (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)
(1 row)

test=# select ('{a,b,c}'::text[])::text;
  text   
---------
 {a,b,c}
(1 row)

But not on 8.2.23:

test=# select version();
                                                   version                                                   
-------------------------------------------------------------------------------------------------------------
 PostgreSQL 8.2.23 on x86_64-unknown-linux-gnu, compiled by GCC gcc47 (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)
(1 row)

test=# select ('{a,b,c}'::text[])::text;
ERROR:  cannot cast type text[] to text
LINE 1: select ('{a,b,c}'::text[])::text;
1

There are 1 best solutions below

2
On

If I don't understand your question clearly : but following is a way to do text to array and array to text conversion

array_to_string(anyarray, text)

Example:
postgres=# select * from array_to_string(array[1,2,3],'');
 array_to_string 
-----------------
 123
(1 row)

string_to_array(text, text) :

postgres=# select string_to_array('xx~^~yy~^~zz', '~^~');
 string_to_array 
-----------------
 {xx,yy,zz}
(1 row)

if you want to read more about array functions have a look: http://www.postgresql.org/docs/8.2/static/functions-array.html

Update #1: For multi dimensional array:

CREATE OR REPLACE FUNCTION aaa(anyarray,text)
RETURNS SETOF text
LANGUAGE plpgsql
AS $function$
DECLARE s $1%type;
BEGIN
FOREACH s SLICE 1 IN ARRAY $1 LOOP
RETURN NEXT array_to_string(s,$2);
END LOOP;
RETURN;
END;
$function$;

postgres=# select aaa('{{a,b,c},{x,y,z}}'::text[], ',');
  aaa  
-------
 a,b,c
 x,y,z
(2 rows)

postgres=# select aaa('{a,b,c}'::text[], ',');
  aaa  
-------
 a,b,c
(1 row)