]> granicus.if.org Git - postgresql/commitdiff
array_length() function, and for SQL compatibility also cardinality()
authorPeter Eisentraut <peter_e@gmx.net>
Wed, 12 Nov 2008 13:09:28 +0000 (13:09 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Wed, 12 Nov 2008 13:09:28 +0000 (13:09 +0000)
function as a special case.

This version still has the suspicious behavior of returning null for an
empty array (rather than zero), but this may need a wholesale revision of
empty array behavior, currently under discussion.

Jim Nasby, Robert Haas, Peter Eisentraut

doc/src/sgml/array.sgml
doc/src/sgml/func.sgml
src/backend/utils/adt/arrayfuncs.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/utils/array.h
src/test/regress/expected/arrays.out
src/test/regress/sql/arrays.sql

index 4d762c53d3575aa152f40a2e9604bea3d200f14b..08a3ee021d2359e4cffe3413b77be7a4b9f5aa39 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.67 2008/10/29 11:24:52 petere Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.68 2008/11/12 13:09:27 petere Exp $ -->
 
 <sect1 id="arrays">
  <title>Arrays</title>
@@ -324,6 +324,18 @@ SELECT array_upper(schedule, 1) FROM sal_emp WHERE name = 'Carol';
 -------------
            2
 (1 row)
+</programlisting>
+
+ <function>array_length</function> will return the length of a specified
+ array dimension:
+
+<programlisting>
+SELECT array_length(schedule, 1) FROM sal_emp WHERE name = 'Carol';
+
+ array_length
+--------------
+            2
+(1 row)
 </programlisting>
  </para>
  </sect2>
index 1e329904512b826d1c69742d80e5ff6dde8ad875..85403e2c9f72f1a9799716549be71f898d254492 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.456 2008/11/07 22:54:41 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.457 2008/11/12 13:09:27 petere Exp $ -->
 
  <chapter id="functions">
   <title>Functions and Operators</title>
@@ -9408,6 +9408,17 @@ SELECT NULLIF(value, '(none)') ...
         <entry><literal>array_fill(7, ARRAY[3], ARRAY[2])</literal></entry>
         <entry><literal>[2:4]={7,7,7}</literal></entry>
        </row>
+       <row>
+        <entry>
+         <literal>
+          <function>array_length</function>(<type>anyarray</type>, <type>int</type>)
+         </literal>
+        </entry>
+        <entry><type>int</type></entry>
+        <entry>returns the length of the requested array dimension</entry>
+        <entry><literal>array_length(array[1,2,3], 1)</literal></entry>
+        <entry><literal>3</literal></entry>
+       </row>
        <row>
         <entry>
          <literal>
@@ -9452,6 +9463,19 @@ SELECT NULLIF(value, '(none)') ...
         <entry><literal>array_upper(ARRAY[1,2,3,4], 1)</literal></entry>
         <entry><literal>4</literal></entry>
        </row>
+       <row>
+        <entry>
+         <literal>
+          <function>cardinality</function>(<type>anyarray</type>)
+         </literal>
+        </entry>
+        <entry><type>int</type></entry>
+        <entry>returns the length of the first dimension of the array
+        (special case of <function>array_length</function> for SQL
+        compatibility)</entry>
+        <entry><literal>cardinality(array[1,2,3])</literal></entry>
+        <entry><literal>3</literal></entry>
+       </row>
        <row>
         <entry>
          <literal>
index 97dc3dc6c838879d71dbb933802e1eb9c51a651f..9d2b036897be76188e3bd82d0444835005f5f4ec 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.148 2008/11/04 14:49:11 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.149 2008/11/12 13:09:27 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1640,6 +1640,34 @@ array_upper(PG_FUNCTION_ARGS)
        PG_RETURN_INT32(result);
 }
 
+/*
+ * array_length :
+ *             returns the length, of the dimension requested, for
+ *             the array pointed to by "v", as an int4
+ */
+Datum
+array_length(PG_FUNCTION_ARGS)
+{
+       ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);
+       int                     reqdim = PG_GETARG_INT32(1);
+       int                *dimv;
+       int                     result;
+
+       /* Sanity check: does it look like an array at all? */
+       if (ARR_NDIM(v) <= 0 || ARR_NDIM(v) > MAXDIM)
+               PG_RETURN_NULL();
+
+       /* Sanity check: was the requested dim valid */
+       if (reqdim <= 0 || reqdim > ARR_NDIM(v))
+               PG_RETURN_NULL();
+
+       dimv = ARR_DIMS(v);
+
+       result = dimv[reqdim - 1];
+
+       PG_RETURN_INT32(result);
+}
+
 /*
  * array_ref :
  *       This routine takes an array pointer and a subscript array and returns
index 599e01db6a1f2f8464dac9c27b1602adfd68a288..3e7e52b57f001748942ee3bad8b661e3f5863600 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.503 2008/11/09 21:24:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.504 2008/11/12 13:09:27 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200811091
+#define CATALOG_VERSION_NO     200811121
 
 #endif
index ea686c319dd4023067ddd25897773e7eb25c2dee..6288ca4e7708fcdeb44c71e4478f33d020595b37 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.524 2008/11/04 14:49:11 petere Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.525 2008/11/12 13:09:28 petere Exp $
  *
  * NOTES
  *       The script catalog/genbki.sh reads this file and generates .bki
@@ -996,6 +996,10 @@ DATA(insert OID = 2091 (  array_lower         PGNSP PGUID 12 1 0 0 f f t f i 2 23 "22
 DESCR("array lower dimension");
 DATA(insert OID = 2092 (  array_upper     PGNSP PGUID 12 1 0 0 f f t f i 2 23 "2277 23" _null_ _null_ _null_ array_upper _null_ _null_ _null_ ));
 DESCR("array upper dimension");
+DATA(insert OID = 2176 (  array_length     PGNSP PGUID 12 1 0 0 f f t f i 2 23 "2277 23" _null_ _null_ _null_ array_length _null_ _null_ _null_ ));
+DESCR("array length");
+DATA(insert OID = 2179 (  cardinality      PGNSP PGUID 14 1 0 0 f f t f i 1 23 "2277" _null_ _null_ _null_ "select array_length($1, 1)" _null_ _null_ _null_ ));
+DESCR("array length");
 DATA(insert OID = 378 (  array_append     PGNSP PGUID 12 1 0 0 f f f f i 2 2277 "2277 2283" _null_ _null_ _null_ array_push _null_ _null_ _null_ ));
 DESCR("append element onto end of array");
 DATA(insert OID = 379 (  array_prepend    PGNSP PGUID 12 1 0 0 f f f f i 2 2277 "2283 2277" _null_ _null_ _null_ array_push _null_ _null_ _null_ ));
index 6bbc46e13bedd70c5da052b7f146f18750c9644d..33d9ad3207e9ea055f30962feb8e5ce5e3b5a527 100644 (file)
@@ -49,7 +49,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/array.h,v 1.69 2008/11/04 14:49:12 petere Exp $
+ * $PostgreSQL: pgsql/src/include/utils/array.h,v 1.70 2008/11/12 13:09:28 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -199,6 +199,7 @@ 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);
+extern Datum array_length(PG_FUNCTION_ARGS);
 extern Datum array_larger(PG_FUNCTION_ARGS);
 extern Datum array_smaller(PG_FUNCTION_ARGS);
 extern Datum generate_subscripts(PG_FUNCTION_ARGS);
index c538fad621d245ba547bfdf6a8bd1f66c12bb3fd..804d52b7982aae7939ef76d06d02cfc65b7ed549 100644 (file)
@@ -1075,3 +1075,53 @@ select array_to_string(string_to_array('1|2|3', '|'), '|');
  1|2|3
 (1 row)
 
+select array_length(array[1,2,3], 1);
+ array_length 
+--------------
+            3
+(1 row)
+
+select array_length(array[[1,2,3], [4,5,6]], 0);
+ array_length 
+--------------
+             
+(1 row)
+
+select array_length(array[[1,2,3], [4,5,6]], 1);
+ array_length 
+--------------
+            2
+(1 row)
+
+select array_length(array[[1,2,3], [4,5,6]], 2);
+ array_length 
+--------------
+            3
+(1 row)
+
+select array_length(array[[1,2,3], [4,5,6]], 3);
+ array_length 
+--------------
+             
+(1 row)
+
+select cardinality(array[1,2,3]);
+ cardinality 
+-------------
+           3
+(1 row)
+
+select cardinality(array[[1,2,3], [4,5,6]]);
+ cardinality 
+-------------
+           2
+(1 row)
+
+select c, cardinality(c), d, cardinality(d) from arrtest;
+         c         | cardinality |       d       | cardinality 
+-------------------+-------------+---------------+-------------
+ {}                |             | {}            |            
+ {foobar,new_word} |           2 | {{elt1,elt2}} |           1
+ {foo,new_word}    |           2 | {bar,foo}     |           2
+(3 rows)
+
index a15b81ab286fcc5a5f6d7db3d0d4d073a66f41b1..04b19a4acea28a6a28763f0892a3963db0e197d8 100644 (file)
@@ -386,3 +386,12 @@ select string_to_array('1|2|3', NULL);
 select string_to_array(NULL, '|');
 
 select array_to_string(string_to_array('1|2|3', '|'), '|');
+
+select array_length(array[1,2,3], 1);
+select array_length(array[[1,2,3], [4,5,6]], 0);
+select array_length(array[[1,2,3], [4,5,6]], 1);
+select array_length(array[[1,2,3], [4,5,6]], 2);
+select array_length(array[[1,2,3], [4,5,6]], 3);
+select cardinality(array[1,2,3]);
+select cardinality(array[[1,2,3], [4,5,6]]);
+select c, cardinality(c), d, cardinality(d) from arrtest;