On 29-04-2026 12:45, Adriano dos Santos Fernandes wrote:
> Custom aggregate functions extend `CREATE FUNCTION` with an `AGGREGATE`
> form implemented in PSQL.
[..]
> ## Execution Model
>
> An aggregate function is invoked once for each aggregate instance:
> - once per group in grouped aggregation
> - once per window frame in windowed aggregation
My mental model conflicts with your use of "once" here. If I understand
correctly, it is invoked *for each* row (i.e. step) in the
group/partition, restoring the function state for that group/partition,
so use of once seems off to me.
> For each instance:
> 1. A private execution context is allocated
> 2. Local variables declared in the routine body start as `NULL`
> 3. `ON START DO` is executed once, if present
What are the values of the function parameters in ON START? Or are the
parameters not accessible then?
> 4. `ON STEP DO` is executed for each qualifying row
Why the term ON STEP, why not ON ROW, or maybe ON VALUE?
> 5. `ON FINISH DO` is executed once and must return the aggregate result
Same as for 3, What are the values of the function parameters in ON FINISH?
> Local variables declared in the routine body are visible to `ON START
> DO`, `ON STEP DO` and `ON FINISH DO`, and persist between step calls for
> the same aggregate instance.
See also my earlier comment regarding once.
> ## Invocation
>
> Aggregate functions are called using normal function call syntax:
>
> ```sql
> <aggregate-name>(<args>)
> <aggregate-name>(<args>) filter (where <condition>)
> <aggregate-name>(<args>) over (<window-specification>)
> ```
>
> They are valid only in aggregate-capable SQL contexts, such as:
> - the select list of aggregate queries
> - `HAVING`
> - `ORDER BY`
> - windowed `OVER (...)` usage
Do they work with window frames like BETWEEN UNBOUNDED PRECEDING AND
CURRENT ROW, or, say BETWEEN 10 PRECEDING AND 10 FOLLOWING, if so how?
Mark
--
Mark Rotteveel