|
|
|
|
@ -283,8 +283,11 @@ boolge(PG_FUNCTION_ARGS) |
|
|
|
|
* boolean-and and boolean-or aggregates. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
/* function for standard EVERY aggregate implementation conforming to SQL 2003.
|
|
|
|
|
* must be strict. It is also named bool_and for homogeneity. |
|
|
|
|
/*
|
|
|
|
|
* Function for standard EVERY aggregate conforming to SQL 2003. |
|
|
|
|
* The aggregate is also named bool_and for consistency. |
|
|
|
|
* |
|
|
|
|
* Note: this is only used in plain aggregate mode, not moving-aggregate mode. |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
booland_statefunc(PG_FUNCTION_ARGS) |
|
|
|
|
@ -292,11 +295,109 @@ booland_statefunc(PG_FUNCTION_ARGS) |
|
|
|
|
PG_RETURN_BOOL(PG_GETARG_BOOL(0) && PG_GETARG_BOOL(1)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* function for standard ANY/SOME aggregate conforming to SQL 2003.
|
|
|
|
|
* must be strict. The name of the aggregate is bool_or. See the doc. |
|
|
|
|
/*
|
|
|
|
|
* Function for standard ANY/SOME aggregate conforming to SQL 2003. |
|
|
|
|
* The aggregate is named bool_or, because ANY/SOME have parsing conflicts. |
|
|
|
|
* |
|
|
|
|
* Note: this is only used in plain aggregate mode, not moving-aggregate mode. |
|
|
|
|
*/ |
|
|
|
|
Datum |
|
|
|
|
boolor_statefunc(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
PG_RETURN_BOOL(PG_GETARG_BOOL(0) || PG_GETARG_BOOL(1)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
typedef struct BoolAggState |
|
|
|
|
{ |
|
|
|
|
int64 aggcount; /* number of non-null values aggregated */ |
|
|
|
|
int64 aggtrue; /* number of values aggregated that are true */ |
|
|
|
|
} BoolAggState; |
|
|
|
|
|
|
|
|
|
static BoolAggState * |
|
|
|
|
makeBoolAggState(FunctionCallInfo fcinfo) |
|
|
|
|
{ |
|
|
|
|
BoolAggState *state; |
|
|
|
|
MemoryContext agg_context; |
|
|
|
|
|
|
|
|
|
if (!AggCheckCallContext(fcinfo, &agg_context)) |
|
|
|
|
elog(ERROR, "aggregate function called in non-aggregate context"); |
|
|
|
|
|
|
|
|
|
state = (BoolAggState *) MemoryContextAlloc(agg_context, |
|
|
|
|
sizeof(BoolAggState)); |
|
|
|
|
state->aggcount = 0; |
|
|
|
|
state->aggtrue = 0; |
|
|
|
|
|
|
|
|
|
return state; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Datum |
|
|
|
|
bool_accum(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
BoolAggState *state; |
|
|
|
|
|
|
|
|
|
state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0); |
|
|
|
|
|
|
|
|
|
/* Create the state data on first call */ |
|
|
|
|
if (state == NULL) |
|
|
|
|
state = makeBoolAggState(fcinfo); |
|
|
|
|
|
|
|
|
|
if (!PG_ARGISNULL(1)) |
|
|
|
|
{ |
|
|
|
|
state->aggcount++; |
|
|
|
|
if (PG_GETARG_BOOL(1)) |
|
|
|
|
state->aggtrue++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PG_RETURN_POINTER(state); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Datum |
|
|
|
|
bool_accum_inv(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
BoolAggState *state; |
|
|
|
|
|
|
|
|
|
state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0); |
|
|
|
|
|
|
|
|
|
/* bool_accum should have created the state data */ |
|
|
|
|
if (state == NULL) |
|
|
|
|
elog(ERROR, "bool_accum_inv called with NULL state"); |
|
|
|
|
|
|
|
|
|
if (!PG_ARGISNULL(1)) |
|
|
|
|
{ |
|
|
|
|
state->aggcount--; |
|
|
|
|
if (PG_GETARG_BOOL(1)) |
|
|
|
|
state->aggtrue--; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
PG_RETURN_POINTER(state); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Datum |
|
|
|
|
bool_alltrue(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
BoolAggState *state; |
|
|
|
|
|
|
|
|
|
state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0); |
|
|
|
|
|
|
|
|
|
/* if there were no non-null values, return NULL */ |
|
|
|
|
if (state == NULL || state->aggcount == 0) |
|
|
|
|
PG_RETURN_NULL(); |
|
|
|
|
|
|
|
|
|
/* true if all non-null values are true */ |
|
|
|
|
PG_RETURN_BOOL(state->aggtrue == state->aggcount); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Datum |
|
|
|
|
bool_anytrue(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
BoolAggState *state; |
|
|
|
|
|
|
|
|
|
state = PG_ARGISNULL(0) ? NULL : (BoolAggState *) PG_GETARG_POINTER(0); |
|
|
|
|
|
|
|
|
|
/* if there were no non-null values, return NULL */ |
|
|
|
|
if (state == NULL || state->aggcount == 0) |
|
|
|
|
PG_RETURN_NULL(); |
|
|
|
|
|
|
|
|
|
/* true if any non-null value is true */ |
|
|
|
|
PG_RETURN_BOOL(state->aggtrue > 0); |
|
|
|
|
} |
|
|
|
|
|