*** a/doc/src/sgml/array.sgml --- b/doc/src/sgml/array.sgml *************** *** 338,343 **** SELECT array_length(schedule, 1) FROM sal_emp WHERE name = 'Carol'; --- 338,356 ---- 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) + *** a/doc/src/sgml/func.sgml --- b/doc/src/sgml/func.sgml *************** *** 11009,11014 **** SELECT NULLIF(value, '(none)') ... --- 11009,11017 ---- array_upper + cardinality + + string_to_array *************** *** 11167,11172 **** SELECT NULLIF(value, '(none)') ... --- 11170,11186 ---- + 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 + + + + string_to_array(text, text , text) *** a/src/backend/utils/adt/arrayfuncs.c --- b/src/backend/utils/adt/arrayfuncs.c *************** *** 1740,1745 **** array_length(PG_FUNCTION_ARGS) --- 1740,1766 ---- } /* + * array_cardinality: + * returns the total number of elements in an array + */ + Datum + array_cardinality(PG_FUNCTION_ARGS) + { + ArrayType *v = PG_GETARG_ARRAYTYPE_P(0); + int *dimv; + int i; + int cardinality; + + dimv = ARR_DIMS(v); + cardinality = 1; + for (i = 0; i < ARR_NDIM(v); i++) + cardinality *= dimv[i]; + + PG_RETURN_INT32(cardinality); + } + + + /* * array_ref : * This routine takes an array pointer and a subscript array and returns * the referenced item as a Datum. Note that for a pass-by-reference *** a/src/include/catalog/pg_proc.h --- b/src/include/catalog/pg_proc.h *************** *** 840,845 **** DATA(insert OID = 2092 ( array_upper PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 --- 840,847 ---- 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_ )); *** a/src/include/utils/array.h --- b/src/include/utils/array.h *************** *** 204,209 **** extern Datum array_dims(PG_FUNCTION_ARGS); --- 204,210 ---- 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); *** a/src/test/regress/expected/arrays.out --- b/src/test/regress/expected/arrays.out *************** *** 1455,1460 **** select array_length(array[[1,2,3], [4,5,6]], 3); --- 1455,1502 ---- (1 row) + select cardinality(NULL::int[]); + cardinality + ------------- + + (1 row) + + select cardinality('{}'::int[]); + cardinality + ------------- + 1 + (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 -------------------------------------- *** a/src/test/regress/sql/arrays.sql --- b/src/test/regress/sql/arrays.sql *************** *** 419,424 **** select array_length(array[[1,2,3], [4,5,6]], 1); --- 419,432 ---- 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;