Implement max() and min() aggregates for array types. Patch from Koju

Iijima, reviewed by Neil Conway. Catalog version number bumped,
regression tests updated.
This commit is contained in:
Neil Conway 2005-02-28 03:45:24 +00:00
parent 517872c566
commit 484f0464ff
8 changed files with 118 additions and 9 deletions

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.238 2005/02/11 04:31:54 momjian Exp $
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.239 2005/02/28 03:45:20 neilc Exp $
PostgreSQL documentation
-->
@ -7161,7 +7161,7 @@ SELECT NULLIF(value, '(none)') ...
<row>
<entry><function>max(<replaceable class="parameter">expression</replaceable>)</function></entry>
<entry>any numeric, string, or date/time type</entry>
<entry>any array, numeric, string, or date/time type</entry>
<entry>same as argument type</entry>
<entry>
maximum value of <replaceable
@ -7172,7 +7172,7 @@ SELECT NULLIF(value, '(none)') ...
<row>
<entry><function>min(<replaceable class="parameter">expression</replaceable>)</function></entry>
<entry>any numeric, string, or date/time type</entry>
<entry>any array, numeric, string, or date/time type</entry>
<entry>same as argument type</entry>
<entry>
minimum value of <replaceable

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.115 2004/12/31 22:01:21 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.116 2005/02/28 03:45:21 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -3387,3 +3387,33 @@ makeMdArrayResult(ArrayBuildState *astate,
return PointerGetDatum(result);
}
Datum
array_larger(PG_FUNCTION_ARGS)
{
ArrayType *v1,
*v2,
*result;
v1 = PG_GETARG_ARRAYTYPE_P(0);
v2 = PG_GETARG_ARRAYTYPE_P(1);
result = ((array_cmp(fcinfo) > 0) ? v1 : v2);
PG_RETURN_ARRAYTYPE_P(result);
}
Datum
array_smaller(PG_FUNCTION_ARGS)
{
ArrayType *v1,
*v2,
*result;
v1 = PG_GETARG_ARRAYTYPE_P(0);
v2 = PG_GETARG_ARRAYTYPE_P(1);
result = ((array_cmp(fcinfo) < 0) ? v1 : v2);
PG_RETURN_ARRAYTYPE_P(result);
}

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.256 2005/02/27 08:31:30 neilc Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.257 2005/02/28 03:45:21 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200502271
#define CATALOG_VERSION_NO 200502281
#endif

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_aggregate.h,v 1.48 2005/01/28 17:35:53 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_aggregate.h,v 1.49 2005/02/28 03:45:22 neilc Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@ -110,6 +110,7 @@ DATA(insert ( 2127 timestamptz_larger - 1184 _null_ ));
DATA(insert ( 2128 interval_larger - 1186 _null_ ));
DATA(insert ( 2129 text_larger - 25 _null_ ));
DATA(insert ( 2130 numeric_larger - 1700 _null_ ));
DATA(insert ( 2050 array_larger - 2277 _null_ ));
/* min */
DATA(insert ( 2131 int8smaller - 20 _null_ ));
@ -128,6 +129,7 @@ DATA(insert ( 2143 timestamptz_smaller - 1184 _null_ ));
DATA(insert ( 2144 interval_smaller - 1186 _null_ ));
DATA(insert ( 2145 text_smaller - 25 _null_ ));
DATA(insert ( 2146 numeric_smaller - 1700 _null_ ));
DATA(insert ( 2051 array_smaller - 2277 _null_ ));
/*
* Using int8inc for count() is cheating a little, since it really only

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.351 2005/02/27 08:31:30 neilc Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.352 2005/02/28 03:45:22 neilc Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@ -1028,6 +1028,10 @@ DATA(insert OID = 394 ( string_to_array PGNSP PGUID 12 f f t f i 2 1009 "25 2
DESCR("split delimited text into text[]");
DATA(insert OID = 395 ( array_to_string PGNSP PGUID 12 f f t f i 2 25 "2277 25" _null_ array_to_text - _null_ ));
DESCR("concatenate array elements, using delimiter, into text");
DATA(insert OID = 515 ( array_larger PGNSP PGUID 12 f f t f i 2 2277 "2277 2277" _null_ array_larger - _null_ ));
DESCR("larger of two");
DATA(insert OID = 516 ( array_smaller PGNSP PGUID 12 f f t f i 2 2277 "2277 2277" _null_ array_smaller - _null_ ));
DESCR("smaller of two");
DATA(insert OID = 760 ( smgrin PGNSP PGUID 12 f f t f s 1 210 "2275" _null_ smgrin - _null_ ));
DESCR("I/O");
@ -3029,6 +3033,7 @@ DATA(insert OID = 2127 ( max PGNSP PGUID 12 t f f f i 1 1184 "1184" _null_ a
DATA(insert OID = 2128 ( max PGNSP PGUID 12 t f f f i 1 1186 "1186" _null_ aggregate_dummy - _null_ ));
DATA(insert OID = 2129 ( max PGNSP PGUID 12 t f f f i 1 25 "25" _null_ aggregate_dummy - _null_ ));
DATA(insert OID = 2130 ( max PGNSP PGUID 12 t f f f i 1 1700 "1700" _null_ aggregate_dummy - _null_ ));
DATA(insert OID = 2050 ( max PGNSP PGUID 12 t f f f i 1 2277 "2277" _null_ aggregate_dummy - _null_ ));
DATA(insert OID = 2131 ( min PGNSP PGUID 12 t f f f i 1 20 "20" _null_ aggregate_dummy - _null_ ));
DATA(insert OID = 2132 ( min PGNSP PGUID 12 t f f f i 1 23 "23" _null_ aggregate_dummy - _null_ ));
@ -3046,6 +3051,7 @@ DATA(insert OID = 2143 ( min PGNSP PGUID 12 t f f f i 1 1184 "1184" _null_ a
DATA(insert OID = 2144 ( min PGNSP PGUID 12 t f f f i 1 1186 "1186" _null_ aggregate_dummy - _null_ ));
DATA(insert OID = 2145 ( min PGNSP PGUID 12 t f f f i 1 25 "25" _null_ aggregate_dummy - _null_ ));
DATA(insert OID = 2146 ( min PGNSP PGUID 12 t f f f i 1 1700 "1700" _null_ aggregate_dummy - _null_ ));
DATA(insert OID = 2051 ( min PGNSP PGUID 12 t f f f i 1 2277 "2277" _null_ aggregate_dummy - _null_ ));
DATA(insert OID = 2147 ( count PGNSP PGUID 12 t f f f i 1 20 "2276" _null_ aggregate_dummy - _null_ ));

View File

@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.51 2004/12/31 22:03:45 pgsql Exp $
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.52 2005/02/28 03:45:23 neilc Exp $
*
*-------------------------------------------------------------------------
*/
@ -129,6 +129,8 @@ extern Datum array_upper(PG_FUNCTION_ARGS);
extern Datum array_type_coerce(PG_FUNCTION_ARGS);
extern Datum array_type_length_coerce(PG_FUNCTION_ARGS);
extern Datum array_length_coerce(PG_FUNCTION_ARGS);
extern Datum array_larger(PG_FUNCTION_ARGS);
extern Datum array_smaller(PG_FUNCTION_ARGS);
extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx,
int arraylen, int elmlen, bool elmbyval, char elmalign,

View File

@ -483,3 +483,47 @@ select '{
(1 row)
-- all of the above should be accepted
-- tests for array aggregates
CREATE TEMP TABLE arraggtest ( f1 INT[], f2 TEXT[][], f3 FLOAT[]);
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{1,2,3,4}','{{grey,red},{blue,blue}}','{1.6, 0.0}');
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{1,2,3}','{{grey,red},{grey,blue}}','{1.6}');
SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
max | min | max | min | max | min
-----------+---------+--------------------------+--------------------------+---------+-------
{1,2,3,4} | {1,2,3} | {{grey,red},{grey,blue}} | {{grey,red},{blue,blue}} | {1.6,0} | {1.6}
(1 row)
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{3,3,2,4,5,6}','{{white,yellow},{pink,orange}}','{2.1,3.3,1.8,1.7,1.6}');
SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
max | min | max | min | max | min
---------------+---------+--------------------------------+--------------------------+-----------------------+-------
{3,3,2,4,5,6} | {1,2,3} | {{white,yellow},{pink,orange}} | {{grey,red},{blue,blue}} | {2.1,3.3,1.8,1.7,1.6} | {1.6}
(1 row)
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{2}','{{black,red},{green,orange}}','{1.6,2.2,2.6,0.4}');
SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
max | min | max | min | max | min
---------------+---------+--------------------------------+------------------------------+-----------------------+-------
{3,3,2,4,5,6} | {1,2,3} | {{white,yellow},{pink,orange}} | {{black,red},{green,orange}} | {2.1,3.3,1.8,1.7,1.6} | {1.6}
(1 row)
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{4,2,6,7,8,1}','{{red},{black},{purple},{blue},{blue}}',NULL);
SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
max | min | max | min | max | min
---------------+---------+--------------------------------+------------------------------+-----------------------+-------
{4,2,6,7,8,1} | {1,2,3} | {{white,yellow},{pink,orange}} | {{black,red},{green,orange}} | {2.1,3.3,1.8,1.7,1.6} | {1.6}
(1 row)
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{}','{{pink,white,blue,red,grey,orange}}','{2.1,1.87,1.4,2.2}');
SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
max | min | max | min | max | min
---------------+-----+--------------------------------+------------------------------+-----------------------+-------
{4,2,6,7,8,1} | {} | {{white,yellow},{pink,orange}} | {{black,red},{green,orange}} | {2.1,3.3,1.8,1.7,1.6} | {1.6}
(1 row)

View File

@ -217,3 +217,28 @@ select '{
@ 1 hour @ 42 minutes @ 20 seconds
}'::interval[];
-- all of the above should be accepted
-- tests for array aggregates
CREATE TEMP TABLE arraggtest ( f1 INT[], f2 TEXT[][], f3 FLOAT[]);
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{1,2,3,4}','{{grey,red},{blue,blue}}','{1.6, 0.0}');
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{1,2,3}','{{grey,red},{grey,blue}}','{1.6}');
SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{3,3,2,4,5,6}','{{white,yellow},{pink,orange}}','{2.1,3.3,1.8,1.7,1.6}');
SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{2}','{{black,red},{green,orange}}','{1.6,2.2,2.6,0.4}');
SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{4,2,6,7,8,1}','{{red},{black},{purple},{blue},{blue}}',NULL);
SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;
INSERT INTO arraggtest (f1, f2, f3) VALUES
('{}','{{pink,white,blue,red,grey,orange}}','{2.1,1.87,1.4,2.2}');
SELECT max(f1), min(f1), max(f2), min(f2), max(f3), min(f3) FROM arraggtest;