*** ./doc/src/sgml/func.sgml.orig 2010-04-07 08:12:52.000000000 +0200
--- ./doc/src/sgml/func.sgml 2010-05-05 20:36:31.692244426 +0200
***************
*** 4639,4645 ****
! If case-independent matching is specified,
the effect is much as if all case distinctions had vanished from the
alphabet.
When an alphabetic that exists in multiple cases appears as an
--- 4639,4645 ----
! If case-independent matching is specified,
the effect is much as if all case distinctions had vanished from the
alphabet.
When an alphabetic that exists in multiple cases appears as an
***************
*** 9501,9506 ****
--- 9501,9512 ----
string_to_array
+ to_array
+
+
+ to_string
+
+
unnest
***************
*** 9643,9648 ****
--- 9649,9676 ----
+ to_array(text, text , text)
+
+
+ text[]
+ splits string into array elements using supplied delimiter and null string
+ to_array('1,2,3,,5', ',')
+ {1,2,3,4,NULL,5}
+
+
+
+
+ to_string(anyarray, text , text)
+
+
+ text
+ concatenates array elements using supplied delimiter and null string
+ to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*')
+ 1,2,3,*,5
+
+
+
+
unnest(anyarray)
*** ./src/backend/catalog/system_views.sql.orig 2010-04-26 16:22:37.000000000 +0200
--- ./src/backend/catalog/system_views.sql 2010-05-05 19:59:05.256243744 +0200
***************
*** 487,489 ****
--- 487,497 ----
CREATE OR REPLACE FUNCTION
pg_start_backup(label text, fast boolean DEFAULT false)
RETURNS text STRICT VOLATILE LANGUAGE internal AS 'pg_start_backup';
+
+ CREATE OR REPLACE FUNCTION
+ to_string(v anyarray, fldsep text, null_string text DEFAULT '')
+ RETURNS text STRICT IMMUTABLE LANGUAGE internal AS 'to_string';
+
+ CREATE OR REPLACE FUNCTION
+ to_array(inputstr text, fldsep text, null_string text DEFAULT '')
+ RETURNS text[] STRICT IMMUTABLE LANGUAGE internal AS 'to_array';
*** ./src/backend/utils/adt/array_userfuncs.c.orig 2010-02-26 03:01:06.000000000 +0100
--- ./src/backend/utils/adt/array_userfuncs.c 2010-05-05 19:15:45.898243688 +0200
***************
*** 407,415 ****
--- 407,417 ----
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,434 ****
--- 431,437 ----
ndims, MAXDIM)));
dvalues[0] = element;
+ nulls[0] = isNull;
for (i = 0; i < ndims; i++)
{
***************
*** 462,468 ****
typbyval = my_extra->typbyval;
typalign = my_extra->typalign;
! return construct_md_array(dvalues, NULL, ndims, dims, lbs, element_type,
typlen, typbyval, typalign);
}
--- 465,471 ----
typbyval = my_extra->typbyval;
typalign = my_extra->typalign;
! return construct_md_array(dvalues, nulls, ndims, dims, lbs, element_type,
typlen, typbyval, typalign);
}
*** ./src/backend/utils/adt/varlena.c.orig 2010-02-26 03:01:10.000000000 +0100
--- ./src/backend/utils/adt/varlena.c 2010-05-05 20:17:53.657243603 +0200
***************
*** 2965,2980 ****
}
/*
! * text_to_array
! * parse input string
! * return text array of elements
! * based on provided field separator
*/
! Datum
! text_to_array(PG_FUNCTION_ARGS)
{
- text *inputstring = PG_GETARG_TEXT_PP(0);
- text *fldsep = PG_GETARG_TEXT_PP(1);
int inputstring_len;
int fldsep_len;
TextPositionState state;
--- 2965,2986 ----
}
/*
! * Returns true when two text params are same.
*/
! static
! bool text_isequal(text *txt1, text *txt2)
! {
! return DatumGetBool(DirectFunctionCall2(texteq,
! PointerGetDatum(txt1),
! PointerGetDatum(txt2)));
! }
!
! /*
! * common code for text_to_array and to_array functions
! */
! static Datum
! _text_to_array(FunctionCallInfo fcinfo, text *inputstring, text *fldsep, text *null_string, bool *isNull)
{
int inputstring_len;
int fldsep_len;
TextPositionState state;
***************
*** 2985,2993 ****
char *start_ptr;
text *result_text;
ArrayBuildState *astate = NULL;
text_position_setup(inputstring, fldsep, &state);
!
/*
* Note: we check the converted string length, not the original, because
* they could be different if the input contained invalid encoding.
--- 2991,3000 ----
char *start_ptr;
text *result_text;
ArrayBuildState *astate = NULL;
+ bool is_null_string;
text_position_setup(inputstring, fldsep, &state);
!
/*
* Note: we check the converted string length, not the original, because
* they could be different if the input contained invalid encoding.
***************
*** 2999,3005 ****
if (inputstring_len < 1)
{
text_position_cleanup(&state);
! PG_RETURN_NULL();
}
/*
--- 3006,3013 ----
if (inputstring_len < 1)
{
text_position_cleanup(&state);
! *isNull = true;
! return (Datum) 0;
}
/*
***************
*** 3009,3016 ****
if (fldsep_len < 1)
{
text_position_cleanup(&state);
! PG_RETURN_ARRAYTYPE_P(create_singleton_array(fcinfo, TEXTOID,
! PointerGetDatum(inputstring), 1));
}
start_posn = 1;
--- 3017,3026 ----
if (fldsep_len < 1)
{
text_position_cleanup(&state);
! is_null_string = null_string != NULL ? text_isequal(null_string, inputstring) : false;
! *isNull = false;
! return (Datum) create_singleton_array(fcinfo, TEXTOID,
! PointerGetDatum(inputstring), is_null_string, 1);
}
start_posn = 1;
***************
*** 3036,3046 ****
/* must build a temp text datum to pass to accumArrayResult */
result_text = cstring_to_text_with_len(start_ptr, chunk_len);
!
/* stash away this field */
astate = accumArrayResult(astate,
PointerGetDatum(result_text),
! false,
TEXTOID,
CurrentMemoryContext);
--- 3046,3057 ----
/* must build a temp text datum to pass to accumArrayResult */
result_text = cstring_to_text_with_len(start_ptr, chunk_len);
! is_null_string = null_string != NULL ? text_isequal(null_string, result_text) : false;
!
/* stash away this field */
astate = accumArrayResult(astate,
PointerGetDatum(result_text),
! is_null_string,
TEXTOID,
CurrentMemoryContext);
***************
*** 3057,3076 ****
text_position_cleanup(&state);
! PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate,
! CurrentMemoryContext));
}
/*
! * array_to_text
! * concatenate Cstring representation of input array elements
! * using provided field separator
*/
Datum
! array_to_text(PG_FUNCTION_ARGS)
{
- ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
- char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
int nitems,
*dims,
ndims;
--- 3068,3129 ----
text_position_cleanup(&state);
! *isNull = false;
! return makeArrayResult(astate, CurrentMemoryContext);
}
+
/*
! * text_to_array
! * parse input string
! * return text array of elements
! * based on provided field separator
*/
Datum
! text_to_array(PG_FUNCTION_ARGS)
! {
! text *inputstring = PG_GETARG_TEXT_PP(0);
! text *fldsep = PG_GETARG_TEXT_PP(1);
! bool isNull;
! Datum result;
!
! result = _text_to_array(fcinfo, inputstring, fldsep, NULL, &isNull);
!
! if (isNull)
! PG_RETURN_NULL();
! else
! PG_RETURN_ARRAYTYPE_P(result);
! }
!
! /*
! * to_array
! * Parse string, returns array. string defined as nullsym is replaced by NULL.
! * Default value for nullsym is empty string.
! */
! Datum
! to_array(PG_FUNCTION_ARGS)
! {
! text *inputstring = PG_GETARG_TEXT_PP(0);
! text *fldsep = PG_GETARG_TEXT_PP(1);
! text *null_string = PG_GETARG_TEXT_PP(2);
! bool isNull;
! Datum result;
!
! result = _text_to_array(fcinfo, inputstring, fldsep, null_string, &isNull);
!
! if (isNull)
! PG_RETURN_NULL();
! else
! PG_RETURN_ARRAYTYPE_P(result);
! }
!
! /*
! * common code for array_to_text and to_string function. null_string can be
! * NULL (only for array_to_text function).
! */
! static text *
! _array_to_text(FunctionCallInfo fcinfo, ArrayType *v, char *fldsep, char *null_string)
{
int nitems,
*dims,
ndims;
***************
*** 3092,3098 ****
/* if there are no elements, return an empty string */
if (nitems == 0)
! PG_RETURN_TEXT_P(cstring_to_text(""));
element_type = ARR_ELEMTYPE(v);
initStringInfo(&buf);
--- 3145,3151 ----
/* if there are no elements, return an empty string */
if (nitems == 0)
! return cstring_to_text("");
element_type = ARR_ELEMTYPE(v);
initStringInfo(&buf);
***************
*** 3140,3146 ****
/* Get source element, checking for NULL */
if (bitmap && (*bitmap & bitmask) == 0)
{
! /* we ignore nulls */
}
else
{
--- 3193,3207 ----
/* Get source element, checking for NULL */
if (bitmap && (*bitmap & bitmask) == 0)
{
! /* we ignore nulls, when null_string isn't defined (is NULL) */
! if (null_string != NULL)
! {
! if (printed)
! appendStringInfo(&buf, "%s%s", fldsep, null_string);
! else
! appendStringInfoString(&buf, null_string);
! printed = true;
! }
}
else
{
***************
*** 3170,3178 ****
}
}
! PG_RETURN_TEXT_P(cstring_to_text_with_len(buf.data, buf.len));
}
#define HEXBASE 16
/*
* Convert a int32 to a string containing a base 16 (hex) representation of
--- 3231,3269 ----
}
}
! return cstring_to_text_with_len(buf.data, buf.len);
}
+ /*
+ * array_to_text
+ * concatenate Cstring representation of input array elements
+ * using provided field separator
+ */
+ Datum
+ array_to_text(PG_FUNCTION_ARGS)
+ {
+ ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
+ char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
+
+ PG_RETURN_TEXT_P(_array_to_text(fcinfo, v, fldsep, NULL));
+ }
+
+ /*
+ * to_string
+ * concatenate Cstring representation of input array elements
+ * using provided field separator and null string
+ */
+ Datum
+ to_string(PG_FUNCTION_ARGS)
+ {
+ ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
+ char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
+ char *null_string = text_to_cstring(PG_GETARG_TEXT_PP(2));
+
+ PG_RETURN_TEXT_P(_array_to_text(fcinfo, v, fldsep, null_string));
+ }
+
+
#define HEXBASE 16
/*
* Convert a int32 to a string containing a base 16 (hex) representation of
*** ./src/include/catalog/pg_proc.h.orig 2010-02-26 03:01:21.000000000 +0100
--- ./src/include/catalog/pg_proc.h 2010-05-05 19:41:37.518244240 +0200
***************
*** 1022,1027 ****
--- 1022,1031 ----
DESCR("split delimited text into text[]");
DATA(insert OID = 395 ( array_to_string PGNSP PGUID 12 1 0 0 f f f t f i 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 = 950 ( to_array PGNSP PGUID 12 1 0 0 f f f t f i 3 0 1009 "25 25 25" _null_ _null_ _null_ _null_ to_array _null_ _null_ _null_ ));
+ DESCR("split delimited text into text[], possible to set null string");
+ DATA(insert OID = 951 ( to_string PGNSP PGUID 12 1 0 0 f f f t f i 3 0 25 "2277 25 25" _null_ _null_ _null_ _null_ to_string _null_ _null_ _null_ ));
+ DESCR("concatenate array elements, using delimiter, into text, possible to set null string");
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_ ));
*** ./src/include/utils/array.h.orig 2010-01-02 17:58:09.000000000 +0100
--- ./src/include/utils/array.h 2010-05-05 18:02:44.191119209 +0200
***************
*** 274,279 ****
--- 274,280 ----
extern ArrayType *create_singleton_array(FunctionCallInfo fcinfo,
Oid element_type,
Datum element,
+ bool isNull,
int ndims);
extern Datum array_agg_transfn(PG_FUNCTION_ARGS);
*** ./src/include/utils/builtins.h.orig 2010-02-26 03:01:28.000000000 +0100
--- ./src/include/utils/builtins.h 2010-05-05 18:36:03.468243638 +0200
***************
*** 714,719 ****
--- 714,721 ----
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 to_array(PG_FUNCTION_ARGS);
+ extern Datum to_string(PG_FUNCTION_ARGS);
extern Datum to_hex32(PG_FUNCTION_ARGS);
extern Datum to_hex64(PG_FUNCTION_ARGS);
extern Datum md5_text(PG_FUNCTION_ARGS);
*** ./src/test/regress/expected/arrays.out.orig 2010-02-18 19:41:47.000000000 +0100
--- ./src/test/regress/expected/arrays.out 2010-05-05 20:19:26.000000000 +0200
***************
*** 1208,1210 ****
--- 1208,1265 ----
[5:5]={"(42,43)"}
(1 row)
+ -- check to_string and to_array functions
+ select to_array('abc','');
+ to_array
+ ----------
+ {abc}
+ (1 row)
+
+ select to_array('abc','','abc');
+ to_array
+ ----------
+ {NULL}
+ (1 row)
+
+ select to_array('abc',',');
+ to_array
+ ----------
+ {abc}
+ (1 row)
+
+ select to_array('abc',',','abc');
+ to_array
+ ----------
+ {NULL}
+ (1 row)
+
+ select to_array('1,2,3,4,,6',',');
+ to_array
+ ------------------
+ {1,2,3,4,NULL,6}
+ (1 row)
+
+ select to_array('1,2,3,4,,6',',','');
+ to_array
+ ------------------
+ {1,2,3,4,NULL,6}
+ (1 row)
+
+ select to_array('1,2,3,4,*,6',',','*');
+ to_array
+ ------------------
+ {1,2,3,4,NULL,6}
+ (1 row)
+
+ select to_string(array[1,2,3,4,NULL,6],',');
+ to_string
+ ------------
+ 1,2,3,4,,6
+ (1 row)
+
+ select to_string(array[1,2,3,4,NULL,6],',','*');
+ to_string
+ -------------
+ 1,2,3,4,*,6
+ (1 row)
+
*** ./src/test/regress/sql/arrays.sql.orig 2010-02-18 19:41:47.000000000 +0100
--- ./src/test/regress/sql/arrays.sql 2010-05-05 20:13:12.194118475 +0200
***************
*** 412,414 ****
--- 412,426 ----
select * from t1;
update t1 set f1[5].q2 = 43;
select * from t1;
+
+ -- check to_string and to_array functions
+
+ select to_array('abc','');
+ select to_array('abc','','abc');
+ select to_array('abc',',');
+ select to_array('abc',',','abc');
+ select to_array('1,2,3,4,,6',',');
+ select to_array('1,2,3,4,,6',',','');
+ select to_array('1,2,3,4,*,6',',','*');
+ select to_string(array[1,2,3,4,NULL,6],',');
+ select to_string(array[1,2,3,4,NULL,6],',','*');