patch: array_ndims

Started by Robert Haasover 17 years ago6 messages
#1Robert Haas
robertmhaas@gmail.com
2 attachment(s)

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

Attachments:

array_ndims-v1.patchtext/x-diff; name=array_ndims-v1.patchDownload
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.sqlapplication/octet-stream; name=array_to_set.sqlDownload
#2Pavel Stehule
pavel.stehule@gmail.com
In reply to: Robert Haas (#1)
Re: patch: array_ndims

Hello

we talked about these features, but these functionality is solved with
UNNEST operator
http://farrago.sourceforge.net/design/CollectionTypes.html - so if you
like this functionality (I believe, so want it), please implement
UNNEST operator.

Regards
Pavel Stehule

http://www.ibm.com/developerworks/db2/library/techarticle/dm-0710arocena/index.html

2008/10/11 Robert Haas <robertmhaas@gmail.com>:

Show quoted text

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

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Robert Haas
robertmhaas@gmail.com
In reply to: Pavel Stehule (#2)
Re: patch: array_ndims

There's nothing in that functionality that contemplates
multi-dimensional arrays. Since we have multi-dimensional arrays,
oughtn't we provide the basic functions to deal with them?
array_ndims has got to be at least as useful as array_dims (which
returns an difficult-to-parse chunk of text).

...Robert

Show quoted text

On Sat, Oct 11, 2008 at 2:29 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:

Hello

we talked about these features, but these functionality is solved with
UNNEST operator
http://farrago.sourceforge.net/design/CollectionTypes.html - so if you
like this functionality (I believe, so want it), please implement
UNNEST operator.

Regards
Pavel Stehule

http://www.ibm.com/developerworks/db2/library/techarticle/dm-0710arocena/index.html

2008/10/11 Robert Haas <robertmhaas@gmail.com>:

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

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Robert Haas
robertmhaas@gmail.com
In reply to: Robert Haas (#3)
Re: patch: array_ndims

To put that another way, there are other potential uses of this
function. For example, how would you suggest that someone do this?

CREATE TABLE foo (
id serial,
bar int[],
CHECK (array_ndims(bar) = 3)
);

You can hack something together, but it's not particularly nice.

...Robert

Show quoted text

On Sat, Oct 11, 2008 at 7:53 AM, Robert Haas <robertmhaas@gmail.com> wrote:

There's nothing in that functionality that contemplates
multi-dimensional arrays. Since we have multi-dimensional arrays,
oughtn't we provide the basic functions to deal with them?
array_ndims has got to be at least as useful as array_dims (which
returns an difficult-to-parse chunk of text).

...Robert

On Sat, Oct 11, 2008 at 2:29 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:

Hello

we talked about these features, but these functionality is solved with
UNNEST operator
http://farrago.sourceforge.net/design/CollectionTypes.html - so if you
like this functionality (I believe, so want it), please implement
UNNEST operator.

Regards
Pavel Stehule

http://www.ibm.com/developerworks/db2/library/techarticle/dm-0710arocena/index.html

2008/10/11 Robert Haas <robertmhaas@gmail.com>:

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

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Pavel Stehule
pavel.stehule@gmail.com
In reply to: Robert Haas (#3)
Re: patch: array_ndims

2008/10/11 Robert Haas <robertmhaas@gmail.com>:

There's nothing in that functionality that contemplates
multi-dimensional arrays. Since we have multi-dimensional arrays,
oughtn't we provide the basic functions to deal with them?
array_ndims has got to be at least as useful as array_dims (which
returns an difficult-to-parse chunk of text).

I am sorry, It was noise from me. I don't thing so array_ndims is
dificult parsered, but it's boondoggle. So some variants as
array_ndims should be usefull.

Regards
Pavel Stehule

Show quoted text

...Robert

On Sat, Oct 11, 2008 at 2:29 AM, Pavel Stehule <pavel.stehule@gmail.com> wrote:

Hello

we talked about these features, but these functionality is solved with
UNNEST operator
http://farrago.sourceforge.net/design/CollectionTypes.html - so if you
like this functionality (I believe, so want it), please implement
UNNEST operator.

Regards
Pavel Stehule

http://www.ibm.com/developerworks/db2/library/techarticle/dm-0710arocena/index.html

2008/10/11 Robert Haas <robertmhaas@gmail.com>:

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

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#6Peter Eisentraut
peter_e@gmx.net
In reply to: Robert Haas (#1)
Re: patch: array_ndims

Robert Haas wrote:

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.

I have committed your array_ndims function with the addition of a small
regression test, and I changed the return type to integer because that
is what the rest of the array functions use for dimension information as
well.