Commit 484f0464 authored by Neil Conway's avatar Neil Conway

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

Iijima, reviewed by Neil Conway. Catalog version number bumped,
regression tests updated.
parent 517872c5
<!--
$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
......
......@@ -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);
}
......@@ -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
......@@ -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
......
......@@ -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_ ));
......
......@@ -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,
......
......@@ -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)
......@@ -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;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment