Commit 33f43725 authored by Tom Lane's avatar Tom Lane

Add three-parameter forms of array_to_string and string_to_array, to allow

better handling of NULL elements within the arrays.  The third parameter
is a string that should be used to represent a NULL element, or should
be translated into a NULL element, respectively.  If the third parameter
is NULL it behaves the same as the two-parameter form.

There are two incompatible changes in the behavior of the two-parameter form
of string_to_array.  First, it will return an empty (zero-element) array
rather than NULL when the input string is of zero length.  Second, if the
field separator is NULL, the function splits the string into individual
characters, rather than returning NULL as before.  These two changes make
this form fully compatible with the behavior of the new three-parameter form.

Pavel Stehule, reviewed by Brendan Jurd
parent 5148a046
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.525 2010/08/08 19:15:27 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.526 2010/08/10 21:51:00 tgl Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
......@@ -9736,13 +9736,14 @@ SELECT NULLIF(value, '(none)') ...
<row>
<entry>
<literal>
<function>array_to_string</function>(<type>anyarray</type>, <type>text</type>)
<function>array_to_string</function>(<type>anyarray</type>, <type>text</type> <optional>, <type>text</type></optional>)
</literal>
</entry>
<entry><type>text</type></entry>
<entry>concatenates array elements using supplied delimiter</entry>
<entry><literal>array_to_string(ARRAY[1, 2, 3], '~^~')</literal></entry>
<entry><literal>1~^~2~^~3</literal></entry>
<entry>concatenates array elements using supplied delimiter and
optional null string</entry>
<entry><literal>array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*')</literal></entry>
<entry><literal>1,2,3,*,5</literal></entry>
</row>
<row>
<entry>
......@@ -9758,13 +9759,14 @@ SELECT NULLIF(value, '(none)') ...
<row>
<entry>
<literal>
<function>string_to_array</function>(<type>text</type>, <type>text</type>)
<function>string_to_array</function>(<type>text</type>, <type>text</type> <optional>, <type>text</type></optional>)
</literal>
</entry>
<entry><type>text[]</type></entry>
<entry>splits string into array elements using supplied delimiter</entry>
<entry><literal>string_to_array('xx~^~yy~^~zz', '~^~')</literal></entry>
<entry><literal>{xx,yy,zz}</literal></entry>
<entry>splits string into array elements using supplied delimiter and
optional null string</entry>
<entry><literal>string_to_array('xx~^~yy~^~zz', '~^~', 'yy')</literal></entry>
<entry><literal>{xx,NULL,zz}</literal></entry>
</row>
<row>
<entry>
......@@ -9781,6 +9783,34 @@ SELECT NULLIF(value, '(none)') ...
</tgroup>
</table>
<para>
In <function>string_to_array</function>, if the delimiter parameter is
NULL, each character in the input string will become a separate element in
the resulting array. If the delimiter is an empty string, then the entire
input string is returned as a one-element array. Otherwise the input
string is split at each occurrence of the delimiter string.
</para>
<para>
In <function>string_to_array</function>, if the null-string parameter
is omitted or NULL, none of the substrings of the input will be replaced
by NULL.
In <function>array_to_string</function>, if the null-string parameter
is omitted or NULL, any null elements in the array are simply skipped
and not represented in the output string.
</para>
<note>
<para>
There are two differences in the behavior of <function>string_to_array</>
from pre-9.1 versions of <productname>PostgreSQL</>.
First, it will return an empty (zero-element) array rather than NULL when
the input string is of zero length. Second, if the delimiter string is
NULL, the function splits the input into individual characters, rather
than returning NULL as before.
</para>
</note>
<para>
See also <xref linkend="functions-aggregate"> about the aggregate
function <function>array_agg</function> for use with arrays.
......
......@@ -6,7 +6,7 @@
* Copyright (c) 2003-2010, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.35 2010/02/26 02:01:06 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.36 2010/08/10 21:51:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -407,9 +407,11 @@ ArrayType *
create_singleton_array(FunctionCallInfo fcinfo,
Oid element_type,
Datum element,
bool isNull,
int ndims)
{
Datum dvalues[1];
bool nulls[1];
int16 typlen;
bool typbyval;
char typalign;
......@@ -429,6 +431,7 @@ create_singleton_array(FunctionCallInfo fcinfo,
ndims, MAXDIM)));
dvalues[0] = element;
nulls[0] = isNull;
for (i = 0; i < ndims; i++)
{
......@@ -462,7 +465,7 @@ create_singleton_array(FunctionCallInfo fcinfo,
typbyval = my_extra->typbyval;
typalign = my_extra->typalign;
return construct_md_array(dvalues, NULL, ndims, dims, lbs, element_type,
return construct_md_array(dvalues, nulls, ndims, dims, lbs, element_type,
typlen, typbyval, typalign);
}
......
This diff is collapsed.
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.593 2010/08/08 19:15:27 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.594 2010/08/10 21:51:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201008081
#define CATALOG_VERSION_NO 201008101
#endif
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.577 2010/08/08 19:15:27 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.578 2010/08/10 21:51:00 tgl Exp $
*
* NOTES
* The script catalog/genbki.pl reads this file and generates .bki
......@@ -1018,10 +1018,14 @@ DATA(insert OID = 379 ( array_prepend PGNSP PGUID 12 1 0 0 f f f f f i 2 0 2
DESCR("prepend element onto front of array");
DATA(insert OID = 383 ( array_cat PGNSP PGUID 12 1 0 0 f f f f f i 2 0 2277 "2277 2277" _null_ _null_ _null_ _null_ array_cat _null_ _null_ _null_ ));
DESCR("concatenate two arrays");
DATA(insert OID = 394 ( string_to_array PGNSP PGUID 12 1 0 0 f f f t f i 2 0 1009 "25 25" _null_ _null_ _null_ _null_ text_to_array _null_ _null_ _null_ ));
DATA(insert OID = 394 ( string_to_array PGNSP PGUID 12 1 0 0 f f f f f i 2 0 1009 "25 25" _null_ _null_ _null_ _null_ text_to_array _null_ _null_ _null_ ));
DESCR("split delimited text into text[]");
DATA(insert OID = 395 ( array_to_string PGNSP PGUID 12 1 0 0 f f f t f s 2 0 25 "2277 25" _null_ _null_ _null_ _null_ array_to_text _null_ _null_ _null_ ));
DESCR("concatenate array elements, using delimiter, into text");
DATA(insert OID = 376 ( string_to_array PGNSP PGUID 12 1 0 0 f f f f f i 3 0 1009 "25 25 25" _null_ _null_ _null_ _null_ text_to_array_null _null_ _null_ _null_ ));
DESCR("split delimited text into text[], with null string");
DATA(insert OID = 384 ( array_to_string PGNSP PGUID 12 1 0 0 f f f f f s 3 0 25 "2277 25 25" _null_ _null_ _null_ _null_ array_to_text_null _null_ _null_ _null_ ));
DESCR("concatenate array elements, using delimiter and null string, into text");
DATA(insert OID = 515 ( array_larger PGNSP PGUID 12 1 0 0 f f f t f i 2 0 2277 "2277 2277" _null_ _null_ _null_ _null_ array_larger _null_ _null_ _null_ ));
DESCR("larger of two");
DATA(insert OID = 516 ( array_smaller PGNSP PGUID 12 1 0 0 f f f t f i 2 0 2277 "2277 2277" _null_ _null_ _null_ _null_ array_smaller _null_ _null_ _null_ ));
......
......@@ -49,7 +49,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.77 2010/01/02 16:58:09 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.78 2010/08/10 21:51:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -274,6 +274,7 @@ extern Datum array_cat(PG_FUNCTION_ARGS);
extern ArrayType *create_singleton_array(FunctionCallInfo fcinfo,
Oid element_type,
Datum element,
bool isNull,
int ndims);
extern Datum array_agg_transfn(PG_FUNCTION_ARGS);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.353 2010/08/05 18:21:19 tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.354 2010/08/10 21:51:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -716,6 +716,8 @@ extern text *replace_text_regexp(text *src_text, void *regexp,
extern Datum split_text(PG_FUNCTION_ARGS);
extern Datum text_to_array(PG_FUNCTION_ARGS);
extern Datum array_to_text(PG_FUNCTION_ARGS);
extern Datum text_to_array_null(PG_FUNCTION_ARGS);
extern Datum array_to_text_null(PG_FUNCTION_ARGS);
extern Datum to_hex32(PG_FUNCTION_ARGS);
extern Datum to_hex64(PG_FUNCTION_ARGS);
extern Datum md5_text(PG_FUNCTION_ARGS);
......
......@@ -1055,21 +1055,99 @@ select string_to_array('1|2|3', '');
select string_to_array('', '|');
string_to_array
-----------------
{}
(1 row)
select string_to_array('1|2|3', NULL);
string_to_array
-----------------
{1,|,2,|,3}
(1 row)
select string_to_array(NULL, '|') IS NULL;
?column?
----------
t
(1 row)
select string_to_array(NULL, '|');
select string_to_array('abc', '');
string_to_array
-----------------
{abc}
(1 row)
select string_to_array('abc', '', 'abc');
string_to_array
-----------------
{NULL}
(1 row)
select string_to_array('abc', ',');
string_to_array
-----------------
{abc}
(1 row)
select string_to_array('abc', ',', 'abc');
string_to_array
-----------------
{NULL}
(1 row)
select string_to_array('1,2,3,4,,6', ',');
string_to_array
-----------------
{1,2,3,4,"",6}
(1 row)
select string_to_array('1,2,3,4,,6', ',', '');
string_to_array
------------------
{1,2,3,4,NULL,6}
(1 row)
select string_to_array('1,2,3,4,*,6', ',', '*');
string_to_array
------------------
{1,2,3,4,NULL,6}
(1 row)
select array_to_string(NULL::int4[], ',') IS NULL;
?column?
----------
t
(1 row)
select array_to_string('{}'::int4[], ',');
array_to_string
-----------------
(1 row)
select array_to_string(array[1,2,3,4,NULL,6], ',');
array_to_string
-----------------
1,2,3,4,6
(1 row)
select array_to_string(array[1,2,3,4,NULL,6], ',', '*');
array_to_string
-----------------
1,2,3,4,*,6
(1 row)
select array_to_string(array[1,2,3,4,NULL,6], NULL);
array_to_string
-----------------
(1 row)
select array_to_string(array[1,2,3,4,NULL,6], ',', NULL);
array_to_string
-----------------
1,2,3,4,6
(1 row)
select array_to_string(string_to_array('1|2|3', '|'), '|');
array_to_string
-----------------
......
......@@ -383,7 +383,21 @@ select string_to_array('1||2|3||', '||');
select string_to_array('1|2|3', '');
select string_to_array('', '|');
select string_to_array('1|2|3', NULL);
select string_to_array(NULL, '|');
select string_to_array(NULL, '|') IS NULL;
select string_to_array('abc', '');
select string_to_array('abc', '', 'abc');
select string_to_array('abc', ',');
select string_to_array('abc', ',', 'abc');
select string_to_array('1,2,3,4,,6', ',');
select string_to_array('1,2,3,4,,6', ',', '');
select string_to_array('1,2,3,4,*,6', ',', '*');
select array_to_string(NULL::int4[], ',') IS NULL;
select array_to_string('{}'::int4[], ',');
select array_to_string(array[1,2,3,4,NULL,6], ',');
select array_to_string(array[1,2,3,4,NULL,6], ',', '*');
select array_to_string(array[1,2,3,4,NULL,6], NULL);
select array_to_string(array[1,2,3,4,NULL,6], ',', NULL);
select array_to_string(string_to_array('1|2|3', '|'), '|');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment