Skip to content

Commit 5061792

Browse files
committed
bool_or_not_null/bool_and_not_null implementation
1 parent d1a762c commit 5061792

File tree

4 files changed

+78
-16
lines changed

4 files changed

+78
-16
lines changed

src/backend/utils/adt/bool.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ typedef struct BoolAggState
311311
{
312312
int64 aggcount; /* number of non-null values aggregated */
313313
int64 aggtrue; /* number of values aggregated that are true */
314+
int64 aggnull; /* number of values aggregated that are null */
314315
} BoolAggState;
315316

316317
static BoolAggState *
@@ -326,6 +327,7 @@ makeBoolAggState(FunctionCallInfo fcinfo)
326327
sizeof(BoolAggState));
327328
state->aggcount = 0;
328329
state->aggtrue = 0;
330+
state->aggnull = 0;
329331

330332
return state;
331333
}
@@ -347,6 +349,10 @@ bool_accum(PG_FUNCTION_ARGS)
347349
if (PG_GETARG_BOOL(1))
348350
state->aggtrue++;
349351
}
352+
else
353+
{
354+
state->aggnull++;
355+
}
350356

351357
PG_RETURN_POINTER(state);
352358
}
@@ -368,6 +374,10 @@ bool_accum_inv(PG_FUNCTION_ARGS)
368374
if (PG_GETARG_BOOL(1))
369375
state->aggtrue--;
370376
}
377+
else
378+
{
379+
state->aggnull--;
380+
}
371381

372382
PG_RETURN_POINTER(state);
373383
}
@@ -401,3 +411,41 @@ bool_anytrue(PG_FUNCTION_ARGS)
401411
/* true if any non-null value is true */
402412
PG_RETURN_BOOL(state->aggtrue > 0);
403413
}
414+
415+
Datum
416+
bool_alltrue_notnull(PG_FUNCTION_ARGS)
417+
{
418+
BoolAggState *state;
419+
420+
state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
421+
422+
/* if there were no non-null values, return NULL */
423+
if (state == NULL || state->aggcount == 0)
424+
PG_RETURN_NULL();
425+
426+
/* If all values are true except some NULLs then return NULL */
427+
if (state->aggtrue == state->aggcount && state->aggnull > 0)
428+
PG_RETURN_NULL();
429+
430+
/* true if all non-null values are true */
431+
PG_RETURN_BOOL(state->aggtrue == state->aggcount);
432+
}
433+
434+
Datum
435+
bool_anytrue_notnull(PG_FUNCTION_ARGS)
436+
{
437+
BoolAggState *state;
438+
439+
state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0);
440+
441+
/* if there were no non-null values, return NULL */
442+
if (state == NULL || state->aggcount == 0)
443+
PG_RETURN_NULL();
444+
445+
/* If all values are false except some NULLs then return NULL */
446+
if (state->aggtrue == 0 && state->aggnull > 0)
447+
PG_RETURN_NULL();
448+
449+
/* true if any non-null value is true */
450+
PG_RETURN_BOOL(state->aggtrue > 0);
451+
}

src/include/catalog/pg_aggregate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ DATA(insert ( 2829 n 0 float8_regr_accum float8_corr - - - f f 0 102
260260
DATA(insert ( 2517 n 0 booland_statefunc - bool_accum bool_accum_inv bool_alltrue f f 58 16 0 2281 16 _null_ _null_ ));
261261
DATA(insert ( 2518 n 0 boolor_statefunc - bool_accum bool_accum_inv bool_anytrue f f 59 16 0 2281 16 _null_ _null_ ));
262262
DATA(insert ( 2519 n 0 booland_statefunc - bool_accum bool_accum_inv bool_alltrue f f 58 16 0 2281 16 _null_ _null_ ));
263+
DATA(insert ( 7650 n 0 bool_accum bool_alltrue_notnull bool_accum bool_accum_inv bool_alltrue_notnull f f 58 2281 16 2281 16 _null_ _null_ ));
264+
DATA(insert ( 7651 n 0 bool_accum bool_anytrue_notnull bool_accum bool_accum_inv bool_anytrue_notnull f f 59 2281 16 2281 16 _null_ _null_ ));
263265

264266
/* bitwise integer */
265267
DATA(insert ( 2236 n 0 int2and - - - - f f 0 21 0 0 0 _null_ _null_ ));

src/include/catalog/pg_proc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4075,13 +4075,21 @@ DATA(insert OID = 3498 ( bool_alltrue PGNSP PGUID 12 1 0 0 0 f f f f t f i
40754075
DESCR("aggregate final function");
40764076
DATA(insert OID = 3499 ( bool_anytrue PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 16 "2281" _null_ _null_ _null_ _null_ _null_ bool_anytrue _null_ _null_ _null_ ));
40774077
DESCR("aggregate final function");
4078+
DATA(insert OID = 7648 ( bool_alltrue_notnull PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 16 "2281" _null_ _null_ _null_ _null_ _null_ bool_alltrue_notnull _null_ _null_ _null_ ));
4079+
DESCR("aggregate final function");
4080+
DATA(insert OID = 7649 ( bool_anytrue_notnull PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 16 "2281" _null_ _null_ _null_ _null_ _null_ bool_anytrue_notnull _null_ _null_ _null_ ));
4081+
DESCR("aggregate final function");
40784082
DATA(insert OID = 2517 ( bool_and PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 16 "16" _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
40794083
DESCR("boolean-and aggregate");
40804084
/* ANY, SOME? These names conflict with subquery operators. See doc. */
40814085
DATA(insert OID = 2518 ( bool_or PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 16 "16" _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
40824086
DESCR("boolean-or aggregate");
40834087
DATA(insert OID = 2519 ( every PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 16 "16" _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
40844088
DESCR("boolean-and aggregate");
4089+
DATA(insert OID = 7650 ( bool_and_not_null PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 16 "16" _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
4090+
DESCR("boolean-and aggregate");
4091+
DATA(insert OID = 7651 ( bool_or_not_null PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 16 "16" _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
4092+
DESCR("boolean-or aggregate");
40854093

40864094
/* bitwise integer aggregates */
40874095
DATA(insert OID = 2236 ( bit_and PGNSP PGUID 12 1 0 0 0 t f f f f f i 1 0 21 "21" _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));

src/test/regress/expected/opr_sanity.out

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,14 +1353,16 @@ SELECT DISTINCT proname, oprname
13531353
FROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p
13541354
WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid
13551355
ORDER BY 1, 2;
1356-
proname | oprname
1357-
----------+---------
1358-
bool_and | <
1359-
bool_or | >
1360-
every | <
1361-
max | >
1362-
min | <
1363-
(5 rows)
1356+
proname | oprname
1357+
-------------------+---------
1358+
bool_and | <
1359+
bool_and_not_null | <
1360+
bool_or | >
1361+
bool_or_not_null | >
1362+
every | <
1363+
max | >
1364+
min | <
1365+
(7 rows)
13641366

13651367
-- Check datatypes match
13661368
SELECT a.aggfnoid::oid, o.oid
@@ -1393,14 +1395,16 @@ WHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND
13931395
amopopr = o.oid AND
13941396
amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')
13951397
ORDER BY 1, 2;
1396-
proname | oprname | amopstrategy
1397-
----------+---------+--------------
1398-
bool_and | < | 1
1399-
bool_or | > | 5
1400-
every | < | 1
1401-
max | > | 5
1402-
min | < | 1
1403-
(5 rows)
1398+
proname | oprname | amopstrategy
1399+
-------------------+---------+--------------
1400+
bool_and | < | 1
1401+
bool_and_not_null | < | 1
1402+
bool_or | > | 5
1403+
bool_or_not_null | > | 5
1404+
every | < | 1
1405+
max | > | 5
1406+
min | < | 1
1407+
(7 rows)
14041408

14051409
-- Check that there are not aggregates with the same name and different
14061410
-- numbers of arguments. While not technically wrong, we have a project policy

0 commit comments

Comments
 (0)