mirror of
https://github.com/postgres/postgres.git
synced 2025-12-12 02:37:31 +03:00
The added aggregates are:
(1) boolean-and and boolean-or aggregates named bool_and and bool_or.
they (SHOULD;-) correspond to standard sql every and some/any aggregates.
they do not have the right name as there is a problem with
the standard and the parser for some/any. Tom also think that
the standard name is misleading because NULL are ignored.
Also add 'every' aggregate.
(2) bitwise integer aggregates named bit_and and bit_or for
int2, int4, int8 and bit types. They are not standard, but I find
them useful. I needed them once.
The patches adds:
- 2 new very short strict functions for boolean aggregates in
src/backed/utils/adt/bool.c,
src/include/utils/builtins.h and src/include/catalog/pg_proc.h
- the new aggregates declared in src/include/catalog/pg_proc.h and
src/include/catalog/pg_aggregate.h
- some documentation and validation about these new aggregates.
Fabien COELHO
This commit is contained in:
@@ -157,3 +157,139 @@ group by ten
|
||||
having exists (select 1 from onek b
|
||||
where sum(distinct a.four + b.four) = b.four);
|
||||
ERROR: aggregates not allowed in WHERE clause
|
||||
--
|
||||
-- test for bitwise integer aggregates
|
||||
--
|
||||
CREATE TEMPORARY TABLE bitwise_test(
|
||||
i2 INT2,
|
||||
i4 INT4,
|
||||
i8 INT8,
|
||||
i INTEGER,
|
||||
x INT2,
|
||||
y BIT(4)
|
||||
);
|
||||
-- empty case
|
||||
SELECT
|
||||
BIT_AND(i2) AS "?",
|
||||
BIT_OR(i4) AS "?"
|
||||
FROM bitwise_test;
|
||||
? | ?
|
||||
---+---
|
||||
|
|
||||
(1 row)
|
||||
|
||||
COPY bitwise_test FROM STDIN NULL 'null';
|
||||
SELECT
|
||||
BIT_AND(i2) AS "1",
|
||||
BIT_AND(i4) AS "1",
|
||||
BIT_AND(i8) AS "1",
|
||||
BIT_AND(i) AS "?",
|
||||
BIT_AND(x) AS "0",
|
||||
BIT_AND(y) AS "0100",
|
||||
BIT_OR(i2) AS "7",
|
||||
BIT_OR(i4) AS "7",
|
||||
BIT_OR(i8) AS "7",
|
||||
BIT_OR(i) AS "?",
|
||||
BIT_OR(x) AS "7",
|
||||
BIT_OR(y) AS "1101"
|
||||
FROM bitwise_test;
|
||||
1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101
|
||||
---+---+---+---+---+------+---+---+---+---+---+------
|
||||
1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101
|
||||
(1 row)
|
||||
|
||||
--
|
||||
-- test boolean aggregates
|
||||
--
|
||||
-- first test all possible transition and final states
|
||||
SELECT
|
||||
-- boolean and transitions
|
||||
-- null because strict
|
||||
booland_statefunc(NULL, NULL) IS NULL AS "t",
|
||||
booland_statefunc(TRUE, NULL) IS NULL AS "t",
|
||||
booland_statefunc(FALSE, NULL) IS NULL AS "t",
|
||||
booland_statefunc(NULL, TRUE) IS NULL AS "t",
|
||||
booland_statefunc(NULL, FALSE) IS NULL AS "t",
|
||||
-- and actual computations
|
||||
booland_statefunc(TRUE, TRUE) AS "t",
|
||||
NOT booland_statefunc(TRUE, FALSE) AS "t",
|
||||
NOT booland_statefunc(FALSE, TRUE) AS "t",
|
||||
NOT booland_statefunc(FALSE, FALSE) AS "t";
|
||||
t | t | t | t | t | t | t | t | t
|
||||
---+---+---+---+---+---+---+---+---
|
||||
t | t | t | t | t | t | t | t | t
|
||||
(1 row)
|
||||
|
||||
SELECT
|
||||
-- boolean or transitions
|
||||
-- null because strict
|
||||
boolor_statefunc(NULL, NULL) IS NULL AS "t",
|
||||
boolor_statefunc(TRUE, NULL) IS NULL AS "t",
|
||||
boolor_statefunc(FALSE, NULL) IS NULL AS "t",
|
||||
boolor_statefunc(NULL, TRUE) IS NULL AS "t",
|
||||
boolor_statefunc(NULL, FALSE) IS NULL AS "t",
|
||||
-- actual computations
|
||||
boolor_statefunc(TRUE, TRUE) AS "t",
|
||||
boolor_statefunc(TRUE, FALSE) AS "t",
|
||||
boolor_statefunc(FALSE, TRUE) AS "t",
|
||||
NOT boolor_statefunc(FALSE, FALSE) AS "t";
|
||||
t | t | t | t | t | t | t | t | t
|
||||
---+---+---+---+---+---+---+---+---
|
||||
t | t | t | t | t | t | t | t | t
|
||||
(1 row)
|
||||
|
||||
CREATE TEMPORARY TABLE bool_test(
|
||||
b1 BOOL,
|
||||
b2 BOOL,
|
||||
b3 BOOL,
|
||||
b4 BOOL);
|
||||
-- empty case
|
||||
SELECT
|
||||
BOOL_AND(b1) AS "n",
|
||||
BOOL_OR(b3) AS "n"
|
||||
FROM bool_test;
|
||||
n | n
|
||||
---+---
|
||||
|
|
||||
(1 row)
|
||||
|
||||
COPY bool_test FROM STDIN NULL 'null';
|
||||
SELECT
|
||||
BOOL_AND(b1) AS "f",
|
||||
BOOL_AND(b2) AS "t",
|
||||
BOOL_AND(b3) AS "f",
|
||||
BOOL_AND(b4) AS "n",
|
||||
BOOL_AND(NOT b2) AS "f",
|
||||
BOOL_AND(NOT b3) AS "t"
|
||||
FROM bool_test;
|
||||
f | t | f | n | f | t
|
||||
---+---+---+---+---+---
|
||||
f | t | f | | f | t
|
||||
(1 row)
|
||||
|
||||
SELECT
|
||||
EVERY(b1) AS "f",
|
||||
EVERY(b2) AS "t",
|
||||
EVERY(b3) AS "f",
|
||||
EVERY(b4) AS "n",
|
||||
EVERY(NOT b2) AS "f",
|
||||
EVERY(NOT b3) AS "t"
|
||||
FROM bool_test;
|
||||
f | t | f | n | f | t
|
||||
---+---+---+---+---+---
|
||||
f | t | f | | f | t
|
||||
(1 row)
|
||||
|
||||
SELECT
|
||||
BOOL_OR(b1) AS "t",
|
||||
BOOL_OR(b2) AS "t",
|
||||
BOOL_OR(b3) AS "f",
|
||||
BOOL_OR(b4) AS "n",
|
||||
BOOL_OR(NOT b2) AS "f",
|
||||
BOOL_OR(NOT b3) AS "t"
|
||||
FROM bool_test;
|
||||
t | t | f | n | f | t
|
||||
---+---+---+---+---+---
|
||||
t | t | f | | f | t
|
||||
(1 row)
|
||||
|
||||
|
||||
@@ -62,3 +62,121 @@ select ten, sum(distinct four) from onek a
|
||||
group by ten
|
||||
having exists (select 1 from onek b
|
||||
where sum(distinct a.four + b.four) = b.four);
|
||||
|
||||
--
|
||||
-- test for bitwise integer aggregates
|
||||
--
|
||||
CREATE TEMPORARY TABLE bitwise_test(
|
||||
i2 INT2,
|
||||
i4 INT4,
|
||||
i8 INT8,
|
||||
i INTEGER,
|
||||
x INT2,
|
||||
y BIT(4)
|
||||
);
|
||||
|
||||
-- empty case
|
||||
SELECT
|
||||
BIT_AND(i2) AS "?",
|
||||
BIT_OR(i4) AS "?"
|
||||
FROM bitwise_test;
|
||||
|
||||
COPY bitwise_test FROM STDIN NULL 'null';
|
||||
1 1 1 1 1 B0101
|
||||
3 3 3 null 2 B0100
|
||||
7 7 7 3 4 B1100
|
||||
\.
|
||||
|
||||
SELECT
|
||||
BIT_AND(i2) AS "1",
|
||||
BIT_AND(i4) AS "1",
|
||||
BIT_AND(i8) AS "1",
|
||||
BIT_AND(i) AS "?",
|
||||
BIT_AND(x) AS "0",
|
||||
BIT_AND(y) AS "0100",
|
||||
|
||||
BIT_OR(i2) AS "7",
|
||||
BIT_OR(i4) AS "7",
|
||||
BIT_OR(i8) AS "7",
|
||||
BIT_OR(i) AS "?",
|
||||
BIT_OR(x) AS "7",
|
||||
BIT_OR(y) AS "1101"
|
||||
FROM bitwise_test;
|
||||
|
||||
--
|
||||
-- test boolean aggregates
|
||||
--
|
||||
-- first test all possible transition and final states
|
||||
|
||||
SELECT
|
||||
-- boolean and transitions
|
||||
-- null because strict
|
||||
booland_statefunc(NULL, NULL) IS NULL AS "t",
|
||||
booland_statefunc(TRUE, NULL) IS NULL AS "t",
|
||||
booland_statefunc(FALSE, NULL) IS NULL AS "t",
|
||||
booland_statefunc(NULL, TRUE) IS NULL AS "t",
|
||||
booland_statefunc(NULL, FALSE) IS NULL AS "t",
|
||||
-- and actual computations
|
||||
booland_statefunc(TRUE, TRUE) AS "t",
|
||||
NOT booland_statefunc(TRUE, FALSE) AS "t",
|
||||
NOT booland_statefunc(FALSE, TRUE) AS "t",
|
||||
NOT booland_statefunc(FALSE, FALSE) AS "t";
|
||||
|
||||
SELECT
|
||||
-- boolean or transitions
|
||||
-- null because strict
|
||||
boolor_statefunc(NULL, NULL) IS NULL AS "t",
|
||||
boolor_statefunc(TRUE, NULL) IS NULL AS "t",
|
||||
boolor_statefunc(FALSE, NULL) IS NULL AS "t",
|
||||
boolor_statefunc(NULL, TRUE) IS NULL AS "t",
|
||||
boolor_statefunc(NULL, FALSE) IS NULL AS "t",
|
||||
-- actual computations
|
||||
boolor_statefunc(TRUE, TRUE) AS "t",
|
||||
boolor_statefunc(TRUE, FALSE) AS "t",
|
||||
boolor_statefunc(FALSE, TRUE) AS "t",
|
||||
NOT boolor_statefunc(FALSE, FALSE) AS "t";
|
||||
|
||||
CREATE TEMPORARY TABLE bool_test(
|
||||
b1 BOOL,
|
||||
b2 BOOL,
|
||||
b3 BOOL,
|
||||
b4 BOOL);
|
||||
|
||||
-- empty case
|
||||
SELECT
|
||||
BOOL_AND(b1) AS "n",
|
||||
BOOL_OR(b3) AS "n"
|
||||
FROM bool_test;
|
||||
|
||||
COPY bool_test FROM STDIN NULL 'null';
|
||||
TRUE null FALSE null
|
||||
FALSE TRUE null null
|
||||
null TRUE FALSE null
|
||||
\.
|
||||
|
||||
SELECT
|
||||
BOOL_AND(b1) AS "f",
|
||||
BOOL_AND(b2) AS "t",
|
||||
BOOL_AND(b3) AS "f",
|
||||
BOOL_AND(b4) AS "n",
|
||||
BOOL_AND(NOT b2) AS "f",
|
||||
BOOL_AND(NOT b3) AS "t"
|
||||
FROM bool_test;
|
||||
|
||||
SELECT
|
||||
EVERY(b1) AS "f",
|
||||
EVERY(b2) AS "t",
|
||||
EVERY(b3) AS "f",
|
||||
EVERY(b4) AS "n",
|
||||
EVERY(NOT b2) AS "f",
|
||||
EVERY(NOT b3) AS "t"
|
||||
FROM bool_test;
|
||||
|
||||
SELECT
|
||||
BOOL_OR(b1) AS "t",
|
||||
BOOL_OR(b2) AS "t",
|
||||
BOOL_OR(b3) AS "f",
|
||||
BOOL_OR(b4) AS "n",
|
||||
BOOL_OR(NOT b2) AS "f",
|
||||
BOOL_OR(NOT b3) AS "t"
|
||||
FROM bool_test;
|
||||
|
||||
Reference in New Issue
Block a user