Add a cardinality function for arrays.
authorRobert Haas
Tue, 21 Jan 2014 17:38:53 +0000 (12:38 -0500)
committerRobert Haas
Tue, 21 Jan 2014 17:38:53 +0000 (12:38 -0500)
Unlike our other array functions, this considers the total number of
elements across all dimensions, and returns 0 rather than NULL when the
array has no elements.  But it seems that both of those behaviors are
almost universally disliked, so hopefully that's OK.

Marko Tiikkaja, reviewed by Dean Rasheed and Pavel Stehule

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 8b36d4ab85f93adf89dcd95a976c4fc6f20ee584..9ea10682a56703e1573515cae0c73640c0401b7b 100644 (file)
@@ -337,6 +337,19 @@ SELECT array_length(schedule, 1) FROM sal_emp WHERE name = 'Carol';
 --------------
             2
 (1 row)
+
+
cardinality returns the total number of elements in an
+ array across all dimensions.  It is effectively the number of rows a call to
unnest would yield:
+
+
+SELECT cardinality(schedule) FROM sal_emp WHERE name = 'Carol';
+
+ cardinality 
+-------------
+           4
+(1 row)
 
  
  
index c76d357df2459700e769136b8ea864bae3ed2a45..53021c227d7ea168dee01c0dd1dcc2d6b9325d67 100644 (file)
@@ -11008,6 +11008,9 @@ SELECT NULLIF(value, '(none)') ...
  
     array_upper
   
+  
+    cardinality
+  
   
     string_to_array
   
@@ -11164,6 +11167,17 @@ SELECT NULLIF(value, '(none)') ...
         array_upper(ARRAY[1,8,3,7], 1)
         4
        
+       
+        
+         
+          cardinality(anyarray)
+         
+        
+        int
+        returns the total number of elements in the array, or 0 if the array is empty
+        cardinality(ARRAY[[1,2],[3,4]])
+        4
+       
        
         
          
index d52101663a1cdba2a9f822f06332c0a161835897..311d0c22f065ccc270f60a1c9cbea6620528ce4d 100644 (file)
@@ -1739,6 +1739,18 @@ array_length(PG_FUNCTION_ARGS)
    PG_RETURN_INT32(result);
 }
 
+/*
+ * array_cardinality:
+ *     returns the total number of elements in an array
+ */
+Datum
+array_cardinality(PG_FUNCTION_ARGS)
+{
+   ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);
+   PG_RETURN_INT32(ArrayGetNItems(ARR_NDIM(v), ARR_DIMS(v)));
+}
+
+
 /*
  * array_ref :
  *   This routine takes an array pointer and a subscript array and returns
index 89eb7018f67c5c2fe225341283dad7f643be7903..0aca05741c12568e1a7df7abec9d4e9b0ca9dc3d 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 201312231
+#define CATALOG_VERSION_NO 201401211
 
 #endif
index ab05c460c53e443b9777a364e74e3ec170586416..ad9774c28560dd0126d8dde20629af8e3030b416 100644 (file)
@@ -840,6 +840,8 @@ DATA(insert OID = 2092 (  array_upper      PGNSP PGUID 12 1 0 0 0 f f f f t f i 2
 DESCR("array upper dimension");
 DATA(insert OID = 2176 (  array_length    PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "2277 23" _null_ _null_ _null_ _null_ array_length _null_ _null_ _null_ ));
 DESCR("array length");
+DATA(insert OID = 3179 (  cardinality     PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "2277" _null_ _null_ _null_ _null_ array_cardinality _null_ _null_ _null_ ));
+DESCR("array cardinality");
 DATA(insert OID = 378 (  array_append     PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2277 "2277 2283" _null_ _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 0 f f f f f f i 2 0 2277 "2283 2277" _null_ _null_ _null_ _null_ array_push _null_ _null_ _null_ ));
index f6135a6cbb62a7ce01ecce80057555dab4d419c3..9bbfaae85ef18fae3fa9695441f4f02858ec5f27 100644 (file)
@@ -204,6 +204,7 @@ 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_cardinality(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 23b3902017bd5a383087a93c67fe710861fb5527..e1b9d7f0a841ec3014adbe7930dc56d912603965 100644 (file)
@@ -1455,6 +1455,48 @@ select array_length(array[[1,2,3], [4,5,6]], 3);
              
 (1 row)
 
+select cardinality(NULL::int[]);
+ cardinality 
+-------------
+            
+(1 row)
+
+select cardinality('{}'::int[]);
+ cardinality 
+-------------
+           0
+(1 row)
+
+select cardinality(array[1,2,3]);
+ cardinality 
+-------------
+           3
+(1 row)
+
+select cardinality('[2:4]={5,6,7}'::int[]);
+ cardinality 
+-------------
+           3
+(1 row)
+
+select cardinality('{{1,2}}'::int[]);
+ cardinality 
+-------------
+           2
+(1 row)
+
+select cardinality('{{1,2},{3,4},{5,6}}'::int[]);
+ cardinality 
+-------------
+           6
+(1 row)
+
+select cardinality('{{{1}},{{2,3},{3,4}}}'::int[]);
+ cardinality 
+-------------
+           8
+(1 row)
+
 select array_agg(unique1) from (select unique1 from tenk1 where unique1 < 15 order by unique1) ss;
               array_agg               
 --------------------------------------
index e4f9f316ce42102dfcf948a1b65e543204607c1d..64630d9ab7817ab2bb1923b6b815867a793dafd9 100644 (file)
@@ -419,6 +419,14 @@ 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(NULL::int[]);
+select cardinality('{}'::int[]);
+select cardinality(array[1,2,3]);
+select cardinality('[2:4]={5,6,7}'::int[]);
+select cardinality('{{1,2}}'::int[]);
+select cardinality('{{1,2},{3,4},{5,6}}'::int[]);
+select cardinality('{{{1}},{{2,3},{3,4}}}'::int[]);
+
 select array_agg(unique1) from (select unique1 from tenk1 where unique1 < 15 order by unique1) ss;
 select array_agg(ten) from (select ten from tenk1 where unique1 < 15 order by unique1) ss;
 select array_agg(nullif(ten, 4)) from (select ten from tenk1 where unique1 < 15 order by unique1) ss;