diff options
author | Peter Eisentraut | 2008-11-12 13:09:28 +0000 |
---|---|---|
committer | Peter Eisentraut | 2008-11-12 13:09:28 +0000 |
commit | 89d8bd3e2275229a0d3168e5e4cb4af51791f935 (patch) | |
tree | c0bec90ee374e1c2e24b69c8f595ff189e1d8cdc | |
parent | 3c9f4290e2814cdf70a5ca3eb9cd0fa67752e744 (diff) |
array_length() function, and for SQL compatibility also cardinality()
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
-rw-r--r-- | doc/src/sgml/array.sgml | 12 | ||||
-rw-r--r-- | doc/src/sgml/func.sgml | 24 | ||||
-rw-r--r-- | src/backend/utils/adt/arrayfuncs.c | 28 | ||||
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.h | 4 | ||||
-rw-r--r-- | src/include/utils/array.h | 1 | ||||
-rw-r--r-- | src/test/regress/expected/arrays.out | 50 | ||||
-rw-r--r-- | src/test/regress/sql/arrays.sql | 9 |
8 files changed, 129 insertions, 1 deletions
diff --git a/doc/src/sgml/array.sgml b/doc/src/sgml/array.sgml index 32fd58138b..84f3ea591a 100644 --- a/doc/src/sgml/array.sgml +++ b/doc/src/sgml/array.sgml @@ -325,6 +325,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> diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 07dcb9baf6..393d4357b3 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -9411,6 +9411,17 @@ SELECT NULLIF(value, '(none)') ... <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> <function>array_lower</function>(<type>anyarray</type>, <type>int</type>) </literal> </entry> @@ -9455,6 +9466,19 @@ SELECT NULLIF(value, '(none)') ... <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> <function>string_to_array</function>(<type>text</type>, <type>text</type>) </literal> </entry> diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index 497d066389..4b32c7a762 100644 --- a/src/backend/utils/adt/arrayfuncs.c +++ b/src/backend/utils/adt/arrayfuncs.c @@ -1641,6 +1641,34 @@ array_upper(PG_FUNCTION_ARGS) } /* + * 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 * the referenced item as a Datum. Note that for a pass-by-reference diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 9bb3c681ae..0860b52f6b 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200811091 +#define CATALOG_VERSION_NO 200811121 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index fe20b01e75..6c8b07a9c2 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -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_ )); diff --git a/src/include/utils/array.h b/src/include/utils/array.h index 500966de65..a26d733f24 100644 --- a/src/include/utils/array.h +++ b/src/include/utils/array.h @@ -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); diff --git a/src/test/regress/expected/arrays.out b/src/test/regress/expected/arrays.out index c538fad621..804d52b798 100644 --- a/src/test/regress/expected/arrays.out +++ b/src/test/regress/expected/arrays.out @@ -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) + diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql index a15b81ab28..04b19a4ace 100644 --- a/src/test/regress/sql/arrays.sql +++ b/src/test/regress/sql/arrays.sql @@ -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; |