After reading Josh Berkus's email suggesting that the intagg module be dropped, I was wondering what would be required to create a array enumerator (variously called unnest, unroll, array_enum, and, as contemplated by the TODO list, array_to_set). Pavel Stehule's generate_subscripts function provides most of what is needed - however, you need to know the number of dimensions in the array, and it appears we don't have a function to provide that information, at least not in a straightforward fashion. That seems like a pretty useful thing to have anyway, so here's a patch to add it.
If you apply it, you can then used the attached PL/pgsql implementation of array_to_set(). I am sure that it would be better and more efficient to implement this directly in C, but as no one has gotten around to that yet this might be kind of handy. It might even be worth adding to the docs, though I'm not sure exactly where. rhaas=# SELECT * FROM array_to_set(ARRAY[1,2,3,4]); array_to_set -------------- 1 2 3 4 (4 rows) rhaas=# SELECT * FROM array_to_set(ARRAY[[1,2,3,4]]); array_to_set -------------- 1 2 3 4 (4 rows) rhaas=# SELECT * FROM array_to_set(ARRAY[[[1,2,3,4]]]); array_to_set -------------- 1 2 3 4 (4 rows) rhaas=# SELECT * FROM array_to_set(ARRAY[[[[1,2,3,4]]]]); array_to_set -------------- 1 2 3 4 (4 rows) rhaas=# SELECT * FROM array_to_set(ARRAY[[[[[1,2,3,4]]]]]); array_to_set -------------- 1 2 3 4 (4 rows) rhaas=# SELECT * FROM array_to_set(ARRAY[[[[[[1,2,3,4]]]]]]); array_to_set -------------- 1 2 3 4 (4 rows) ...Robert
Index: doc/src/sgml/func.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v retrieving revision 1.448 diff -c -r1.448 func.sgml *** doc/src/sgml/func.sgml 3 Oct 2008 07:33:08 -0000 1.448 --- doc/src/sgml/func.sgml 11 Oct 2008 02:19:15 -0000 *************** *** 9367,9372 **** --- 9367,9383 ---- <row> <entry> <literal> + <function>array_ndims</function>(<type>anyarray</type>) + </literal> + </entry> + <entry><type>int2</type></entry> + <entry>the number of dimensions the array has</entry> + <entry><literal>array_ndims(ARRAY[[1,2,3], [4,5,6]])</literal></entry> + <entry><literal>2</literal></entry> + </row> + <row> + <entry> + <literal> <function>array_dims</function>(<type>anyarray</type>) </literal> </entry> Index: src/backend/utils/adt/arrayfuncs.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v retrieving revision 1.147 diff -c -r1.147 arrayfuncs.c *** src/backend/utils/adt/arrayfuncs.c 21 Jul 2008 04:47:00 -0000 1.147 --- src/backend/utils/adt/arrayfuncs.c 11 Oct 2008 02:19:19 -0000 *************** *** 1531,1536 **** --- 1531,1552 ---- } /* + * array_ndims : + * returns the number of dimensions of the array pointed to by "v" + */ + Datum + array_ndims(PG_FUNCTION_ARGS) + { + ArrayType *v = PG_GETARG_ARRAYTYPE_P(0); + + /* Sanity check: does it look like an array at all? */ + if (ARR_NDIM(v) <= 0 || ARR_NDIM(v) > MAXDIM) + PG_RETURN_NULL(); + + PG_RETURN_INT16(ARR_NDIM(v)); + } + + /* * array_dims : * returns the dimensions of the array pointed to by "v", as a "text" */ Index: src/include/catalog/pg_proc.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_proc.h,v retrieving revision 1.518 diff -c -r1.518 pg_proc.h *** src/include/catalog/pg_proc.h 6 Oct 2008 13:05:37 -0000 1.518 --- src/include/catalog/pg_proc.h 11 Oct 2008 02:19:29 -0000 *************** *** 985,990 **** --- 985,991 ---- DESCR("array less than or equal"); DATA(insert OID = 396 ( array_ge PGNSP PGUID 12 1 0 0 f f t f i 2 16 "2277 2277" _null_ _null_ _null_ array_ge _null_ _null_ _null_ )); DESCR("array greater than or equal"); + DATA(insert OID = 748 ( array_ndims PGNSP PGUID 12 1 0 0 f f t f i 1 21 "2277" _null_ _null_ _null_ array_ndims _null_ _null_ _null_ )); DATA(insert OID = 747 ( array_dims PGNSP PGUID 12 1 0 0 f f t f i 1 25 "2277" _null_ _null_ _null_ array_dims _null_ _null_ _null_ )); DESCR("array dimensions"); DATA(insert OID = 750 ( array_in PGNSP PGUID 12 1 0 0 f f t f s 3 2277 "2275 26 23" _null_ _null_ _null_ array_in _null_ _null_ _null_ )); Index: src/include/utils/array.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/utils/array.h,v retrieving revision 1.68 diff -c -r1.68 array.h *** src/include/utils/array.h 16 Jul 2008 00:48:54 -0000 1.68 --- src/include/utils/array.h 11 Oct 2008 02:19:30 -0000 *************** *** 195,200 **** --- 195,201 ---- extern Datum arrayoverlap(PG_FUNCTION_ARGS); extern Datum arraycontains(PG_FUNCTION_ARGS); extern Datum arraycontained(PG_FUNCTION_ARGS); + extern Datum array_ndims(PG_FUNCTION_ARGS); extern Datum array_dims(PG_FUNCTION_ARGS); extern Datum array_lower(PG_FUNCTION_ARGS); extern Datum array_upper(PG_FUNCTION_ARGS);
array_to_set.sql
Description: Binary data
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers