Skip to content

Commit f98f6ee

Browse files
committed
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
1 parent 4c22564 commit f98f6ee

File tree

8 files changed

+135
-7
lines changed

8 files changed

+135
-7
lines changed

doc/src/sgml/array.sgml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.67 2008/10/29 11:24:52 petere Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.68 2008/11/12 13:09:27 petere Exp $ -->
22

33
<sect1 id="arrays">
44
<title>Arrays</title>
@@ -324,6 +324,18 @@ SELECT array_upper(schedule, 1) FROM sal_emp WHERE name = 'Carol';
324324
-------------
325325
2
326326
(1 row)
327+
</programlisting>
328+
329+
<function>array_length</function> will return the length of a specified
330+
array dimension:
331+
332+
<programlisting>
333+
SELECT array_length(schedule, 1) FROM sal_emp WHERE name = 'Carol';
334+
335+
array_length
336+
--------------
337+
2
338+
(1 row)
327339
</programlisting>
328340
</para>
329341
</sect2>

doc/src/sgml/func.sgml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.456 2008/11/07 22:54:41 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.457 2008/11/12 13:09:27 petere Exp $ -->
22

33
<chapter id="functions">
44
<title>Functions and Operators</title>
@@ -9408,6 +9408,17 @@ SELECT NULLIF(value, '(none)') ...
94089408
<entry><literal>array_fill(7, ARRAY[3], ARRAY[2])</literal></entry>
94099409
<entry><literal>[2:4]={7,7,7}</literal></entry>
94109410
</row>
9411+
<row>
9412+
<entry>
9413+
<literal>
9414+
<function>array_length</function>(<type>anyarray</type>, <type>int</type>)
9415+
</literal>
9416+
</entry>
9417+
<entry><type>int</type></entry>
9418+
<entry>returns the length of the requested array dimension</entry>
9419+
<entry><literal>array_length(array[1,2,3], 1)</literal></entry>
9420+
<entry><literal>3</literal></entry>
9421+
</row>
94119422
<row>
94129423
<entry>
94139424
<literal>
@@ -9452,6 +9463,19 @@ SELECT NULLIF(value, '(none)') ...
94529463
<entry><literal>array_upper(ARRAY[1,2,3,4], 1)</literal></entry>
94539464
<entry><literal>4</literal></entry>
94549465
</row>
9466+
<row>
9467+
<entry>
9468+
<literal>
9469+
<function>cardinality</function>(<type>anyarray</type>)
9470+
</literal>
9471+
</entry>
9472+
<entry><type>int</type></entry>
9473+
<entry>returns the length of the first dimension of the array
9474+
(special case of <function>array_length</function> for SQL
9475+
compatibility)</entry>
9476+
<entry><literal>cardinality(array[1,2,3])</literal></entry>
9477+
<entry><literal>3</literal></entry>
9478+
</row>
94559479
<row>
94569480
<entry>
94579481
<literal>

src/backend/utils/adt/arrayfuncs.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.148 2008/11/04 14:49:11 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.149 2008/11/12 13:09:27 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1640,6 +1640,34 @@ array_upper(PG_FUNCTION_ARGS)
16401640
PG_RETURN_INT32(result);
16411641
}
16421642

1643+
/*
1644+
* array_length :
1645+
* returns the length, of the dimension requested, for
1646+
* the array pointed to by "v", as an int4
1647+
*/
1648+
Datum
1649+
array_length(PG_FUNCTION_ARGS)
1650+
{
1651+
ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
1652+
int reqdim = PG_GETARG_INT32(1);
1653+
int *dimv;
1654+
int result;
1655+
1656+
/* Sanity check: does it look like an array at all? */
1657+
if (ARR_NDIM(v) <= 0 || ARR_NDIM(v) > MAXDIM)
1658+
PG_RETURN_NULL();
1659+
1660+
/* Sanity check: was the requested dim valid */
1661+
if (reqdim <= 0 || reqdim > ARR_NDIM(v))
1662+
PG_RETURN_NULL();
1663+
1664+
dimv = ARR_DIMS(v);
1665+
1666+
result = dimv[reqdim - 1];
1667+
1668+
PG_RETURN_INT32(result);
1669+
}
1670+
16431671
/*
16441672
* array_ref :
16451673
* This routine takes an array pointer and a subscript array and returns

src/include/catalog/catversion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
3838
* Portions Copyright (c) 1994, Regents of the University of California
3939
*
40-
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.503 2008/11/09 21:24:33 tgl Exp $
40+
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.504 2008/11/12 13:09:27 petere Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 200811091
56+
#define CATALOG_VERSION_NO 200811121
5757

5858
#endif

src/include/catalog/pg_proc.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.524 2008/11/04 14:49:11 petere Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.525 2008/11/12 13:09:28 petere Exp $
1111
*
1212
* NOTES
1313
* 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
996996
DESCR("array lower dimension");
997997
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_ ));
998998
DESCR("array upper dimension");
999+
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_ ));
1000+
DESCR("array length");
1001+
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_ ));
1002+
DESCR("array length");
9991003
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_ ));
10001004
DESCR("append element onto end of array");
10011005
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_ ));

src/include/utils/array.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
5050
* Portions Copyright (c) 1994, Regents of the University of California
5151
*
52-
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.69 2008/11/04 14:49:12 petere Exp $
52+
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.70 2008/11/12 13:09:28 petere Exp $
5353
*
5454
*-------------------------------------------------------------------------
5555
*/
@@ -199,6 +199,7 @@ extern Datum array_ndims(PG_FUNCTION_ARGS);
199199
extern Datum array_dims(PG_FUNCTION_ARGS);
200200
extern Datum array_lower(PG_FUNCTION_ARGS);
201201
extern Datum array_upper(PG_FUNCTION_ARGS);
202+
extern Datum array_length(PG_FUNCTION_ARGS);
202203
extern Datum array_larger(PG_FUNCTION_ARGS);
203204
extern Datum array_smaller(PG_FUNCTION_ARGS);
204205
extern Datum generate_subscripts(PG_FUNCTION_ARGS);

src/test/regress/expected/arrays.out

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,3 +1075,53 @@ select array_to_string(string_to_array('1|2|3', '|'), '|');
10751075
1|2|3
10761076
(1 row)
10771077

1078+
select array_length(array[1,2,3], 1);
1079+
array_length
1080+
--------------
1081+
3
1082+
(1 row)
1083+
1084+
select array_length(array[[1,2,3], [4,5,6]], 0);
1085+
array_length
1086+
--------------
1087+
1088+
(1 row)
1089+
1090+
select array_length(array[[1,2,3], [4,5,6]], 1);
1091+
array_length
1092+
--------------
1093+
2
1094+
(1 row)
1095+
1096+
select array_length(array[[1,2,3], [4,5,6]], 2);
1097+
array_length
1098+
--------------
1099+
3
1100+
(1 row)
1101+
1102+
select array_length(array[[1,2,3], [4,5,6]], 3);
1103+
array_length
1104+
--------------
1105+
1106+
(1 row)
1107+
1108+
select cardinality(array[1,2,3]);
1109+
cardinality
1110+
-------------
1111+
3
1112+
(1 row)
1113+
1114+
select cardinality(array[[1,2,3], [4,5,6]]);
1115+
cardinality
1116+
-------------
1117+
2
1118+
(1 row)
1119+
1120+
select c, cardinality(c), d, cardinality(d) from arrtest;
1121+
c | cardinality | d | cardinality
1122+
-------------------+-------------+---------------+-------------
1123+
{} | | {} |
1124+
{foobar,new_word} | 2 | {{elt1,elt2}} | 1
1125+
{foo,new_word} | 2 | {bar,foo} | 2
1126+
(3 rows)
1127+

src/test/regress/sql/arrays.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,3 +386,12 @@ select string_to_array('1|2|3', NULL);
386386
select string_to_array(NULL, '|');
387387

388388
select array_to_string(string_to_array('1|2|3', '|'), '|');
389+
390+
select array_length(array[1,2,3], 1);
391+
select array_length(array[[1,2,3], [4,5,6]], 0);
392+
select array_length(array[[1,2,3], [4,5,6]], 1);
393+
select array_length(array[[1,2,3], [4,5,6]], 2);
394+
select array_length(array[[1,2,3], [4,5,6]], 3);
395+
select cardinality(array[1,2,3]);
396+
select cardinality(array[[1,2,3], [4,5,6]]);
397+
select c, cardinality(c), d, cardinality(d) from arrtest;

0 commit comments

Comments
 (0)