mirror of
https://github.com/postgres/postgres.git
synced 2025-07-31 22:04:40 +03:00
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:
@ -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
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -7161,7 +7161,7 @@ SELECT NULLIF(value, '(none)') ...
|
|||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><function>max(<replaceable class="parameter">expression</replaceable>)</function></entry>
|
<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>same as argument type</entry>
|
||||||
<entry>
|
<entry>
|
||||||
maximum value of <replaceable
|
maximum value of <replaceable
|
||||||
@ -7172,7 +7172,7 @@ SELECT NULLIF(value, '(none)') ...
|
|||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry><function>min(<replaceable class="parameter">expression</replaceable>)</function></entry>
|
<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>same as argument type</entry>
|
||||||
<entry>
|
<entry>
|
||||||
minimum value of <replaceable
|
minimum value of <replaceable
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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);
|
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) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200502271
|
#define CATALOG_VERSION_NO 200502281
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* NOTES
|
||||||
* the genbki.sh script reads this file and generates .bki
|
* 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 ( 2128 interval_larger - 1186 _null_ ));
|
||||||
DATA(insert ( 2129 text_larger - 25 _null_ ));
|
DATA(insert ( 2129 text_larger - 25 _null_ ));
|
||||||
DATA(insert ( 2130 numeric_larger - 1700 _null_ ));
|
DATA(insert ( 2130 numeric_larger - 1700 _null_ ));
|
||||||
|
DATA(insert ( 2050 array_larger - 2277 _null_ ));
|
||||||
|
|
||||||
/* min */
|
/* min */
|
||||||
DATA(insert ( 2131 int8smaller - 20 _null_ ));
|
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 ( 2144 interval_smaller - 1186 _null_ ));
|
||||||
DATA(insert ( 2145 text_smaller - 25 _null_ ));
|
DATA(insert ( 2145 text_smaller - 25 _null_ ));
|
||||||
DATA(insert ( 2146 numeric_smaller - 1700 _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
|
* 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) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* 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[]");
|
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_ ));
|
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");
|
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_ ));
|
DATA(insert OID = 760 ( smgrin PGNSP PGUID 12 f f t f s 1 210 "2275" _null_ smgrin - _null_ ));
|
||||||
DESCR("I/O");
|
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 = 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 = 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 = 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 = 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_ ));
|
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 = 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 = 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 = 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_ ));
|
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) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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_coerce(PG_FUNCTION_ARGS);
|
||||||
extern Datum array_type_length_coerce(PG_FUNCTION_ARGS);
|
extern Datum array_type_length_coerce(PG_FUNCTION_ARGS);
|
||||||
extern Datum array_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,
|
extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx,
|
||||||
int arraylen, int elmlen, bool elmbyval, char elmalign,
|
int arraylen, int elmlen, bool elmbyval, char elmalign,
|
||||||
|
@ -483,3 +483,47 @@ select '{
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- all of the above should be accepted
|
-- 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
|
@ 1 hour @ 42 minutes @ 20 seconds
|
||||||
}'::interval[];
|
}'::interval[];
|
||||||
-- all of the above should be accepted
|
-- 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;
|
||||||
|
Reference in New Issue
Block a user