3

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;
Pierre D
  • 24,012
  • 7
  • 60
  • 96
  • 2
    I have read your question three times and still don't understand what you are after. Can it be you are missing the elephant in the room? `any_array_value::text` – Erwin Brandstetter Jun 18 '14 at 00:58
  • Hi @ErwinBrandstetter, `any_array_value::text` doesn't work for me on **PostgreSQL8.2**. I'm editing my question to reflect that. Thx. – Pierre D Jun 18 '14 at 22:21
  • There is *much* that does not work on pg 8.2, which was [released 2006 and has reached EOL long ago](http://www.postgresql.org/support/versioning/). Consider upgrading to a current version if at all possible. – Erwin Brandstetter Jun 18 '14 at 22:27
  • @ErwinBrandstetter: of course I would if I could... I'm an avid reader of your answers and tips/tricks, so I'm aware of what I'm missing (and of the fact that you barely remember what 8.2 felt like ;-) )... But: I'm using Greenplum (and I otherwise love it). So that's why I put **PostgreSQL 8.2** in bold in the question. Best, – Pierre D Jun 18 '14 at 22:32
  • 1
    Greenplum Database is not PostgreSQL. It is a FORK of PostgreSQL 8.2. It's fine to ask about Greenplum here, but it isn't PostgreSQL, so don't just say you're asking about PostgreSQL. Doing so wastes your time and ours. (Also, I almost never see Greenplum users answering on Stack Overflow, so you might want to try their forums or whatever). – Craig Ringer Jun 19 '14 at 05:13
  • @CraigRinger: you are wrong in assuming that the question is Greenplum-centric. It is not. Please see my edited question; it has nothing to do with Greenplum and everything to do with PostgreSQL 8.2. It's easy enough to verify it, BTW, so please exercise caution before making certain assertions with regard to time-waste etc. I agree that Greenplum is only _based_ on PG8.2, but language-wise it is quite close. – Pierre D Jun 19 '14 at 07:42
  • Fair point. Nonetheless, always mention if you're using Greenplum unless you've already verified it on stock PostgreSQL too. – Craig Ringer Jun 19 '14 at 07:46
  • You can be sure that I will keep the vanilla pg8.2.23 around, just so that I can avoid all the oopla next time I ask something PG-related on SO. – Pierre D Jun 19 '14 at 07:48

1 Answers1

0

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)
Samurai
  • 201
  • 1
  • 2
  • 11