Reputation: 201
I am creating a user-defined aggregate function that needs an additional parameter. More precisely it is a cumulative (aka window) minimum that takes as second parameter a time interval defining the window. Since the aggregate function operates on my user-defined data types I have conveyed a dummy example that computes the average of the n last values of a column. I am aware that I can solve this dummy problem in PostgreSQL but the purpose of the example is only to highlight my problem.
CREATE FUNCTION lastNavg_transfn(state integer[], next integer, n integer)
RETURNS integer[] AS $$
BEGIN
RETURN array_append(state, next);
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
CREATE FUNCTION lastNavg_finalfn(state integer[], n integer)
RETURNS float AS $$
DECLARE
card integer;
count float;
sum float;
BEGIN
count := 0;
sum := 0;
card := array_length(state, 1);
FOR i IN greatest(1,card-n+1)..card
LOOP
sum := sum + state[i];
count := count + 1;
END LOOP;
RETURN sum/count;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
CREATE AGGREGATE lastNavg(integer, integer) (
SFUNC = lastNavg_transfn,
STYPE = integer[],
INITCOND = '{}',
FINALFUNC = lastNavg_finalfn,
PARALLEL = SAFE
);
I receive the following error
ERROR: function lastnavg_finalfn(integer[]) does not exist
SQL state: 42883
How to tell PostgreSQL that my final function also needs a direct parameter? I am working on PostgreSQL 10.1. I know that according to the documentation direct parameters are only allowed for ordered-set aggregates, but I would also need a direct parameter for "normal" aggregates.
Upvotes: 2
Views: 842
Reputation: 247235
You could define an aggregate with two arguments and supply your additional parameter as constant second argument.
The SFUNC
simply stores the second argument e.g. as 0-th element of the STYPE
integer array.
FINALFUNC
has only a single argument and gets n
from the 0-th element of the array.
If you need a second argument that is not an integer, define a composite type and use that as STYPE
.
Not pretty, but it should do the trick.
Upvotes: 1