Support min/max index optimizations on boolean columns.

Since bool_and() is equivalent to min(), and bool_or() to max(), we might
as well let them be index-optimized in the same way.  The practical value
of this is debatable at best, but it seems nearly cost-free to enable it.
Code-wise, we need only adjust the entries in pg_aggregate.  There is a
measurable planning speed penalty for a query involving one of these
aggregates, but it is only a few percent in simple cases, so that seems
acceptable.

Marti Raudsepp, reviewed by Abhijit Menon-Sen
This commit is contained in:
Tom Lane 2012-02-08 12:41:48 -05:00
parent 3db6524fe6
commit cbba55d6d7
4 changed files with 24 additions and 18 deletions

View File

@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201202082
#define CATALOG_VERSION_NO 201202083
#endif

View File

@ -205,9 +205,9 @@ DATA(insert ( 2828 float8_regr_accum float8_covar_samp 0 1022 "{0,0,0,0,0,0}" )
DATA(insert ( 2829 float8_regr_accum float8_corr 0 1022 "{0,0,0,0,0,0}" ));
/* boolean-and and boolean-or */
DATA(insert ( 2517 booland_statefunc - 0 16 _null_ ));
DATA(insert ( 2518 boolor_statefunc - 0 16 _null_ ));
DATA(insert ( 2519 booland_statefunc - 0 16 _null_ ));
DATA(insert ( 2517 booland_statefunc - 58 16 _null_ ));
DATA(insert ( 2518 boolor_statefunc - 59 16 _null_ ));
DATA(insert ( 2519 booland_statefunc - 58 16 _null_ ));
/* bitwise integer */
DATA(insert ( 2236 int2and - 0 21 _null_ ));

View File

@ -774,16 +774,19 @@ WHERE a.aggfnoid = p.oid AND
(0 rows)
-- Cross-check aggsortop (if present) against pg_operator.
-- We expect to find only "<" for "min" and ">" for "max".
-- We expect to find entries for bool_and, bool_or, every, max, and min.
SELECT DISTINCT proname, oprname
FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p
WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid
ORDER BY 1;
proname | oprname
---------+---------
max | >
min | <
(2 rows)
ORDER BY 1, 2;
proname | oprname
----------+---------
bool_and | <
bool_or | >
every | <
max | >
min | <
(5 rows)
-- Check datatypes match
SELECT a.aggfnoid::oid, o.oid
@ -816,11 +819,14 @@ WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND
amopopr = o.oid AND
amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
ORDER BY 1, 2;
proname | oprname | amopstrategy
---------+---------+--------------
max | > | 5
min | < | 1
(2 rows)
proname | oprname | amopstrategy
----------+---------+--------------
bool_and | < | 1
bool_or | > | 5
every | < | 1
max | > | 5
min | < | 1
(5 rows)
-- Check that there are not aggregates with the same name and different
-- numbers of arguments. While not technically wrong, we have a project policy

View File

@ -626,12 +626,12 @@ WHERE a.aggfnoid = p.oid AND
NOT binary_coercible(p.proargtypes[0], a.aggtranstype);
-- Cross-check aggsortop (if present) against pg_operator.
-- We expect to find only "<" for "min" and ">" for "max".
-- We expect to find entries for bool_and, bool_or, every, max, and min.
SELECT DISTINCT proname, oprname
FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p
WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid
ORDER BY 1;
ORDER BY 1, 2;
-- Check datatypes match