On 21/10/2026 01:14, David Rowley wrote:
> I agree with what Andres mentioned about changing things so we don't
> support calling transition functions directly, as that would allow
> getting rid of various AggCheckCallContext checks that don't need to
> fetch an actual context. The best way I've thought to do that requires
> a new pg_proc column. "procallable", or by using prokind with
> something like PROKIND_INTERNAL. I don't really like the idea of doing
> this by forcing ourselves into having internal states for these byval
> aggregates as a way to block calling due to the INTERNAL parameter.
> That means having to palloc memory for the state that we don't
> currently have to do for these aggregates. Looking at the history of
> int4_sum(), you can see that when we used to have USE_FLOAT8_BYVAL, we
> used to palloc memory for that state for non-USE_FLOAT8_BYVAL builds
> and pass by value for USE_FLOAT8_BYVAL builds. It's easy to assume we
> did the pass-by-value to avoid the palloc.

I think a column like 'procallable' is the best approach. My only concern is how
broadly useful it would be. The use cases I can see:

1. Transition and combine functions could rely on being called only by the
aggregate machinery, so the defensive code could go away. The per-row gain is
minor, but the simplification is real (maybe not so minor for by-val states).
2. No more bug reports caused by SQL calls feeding transition functions with
various flavours of garbage, like the int2_avg_accum_inv case upthread.
3. No mandatory serial/deserial functions and no palloc for states that are
naturally by-value.
4. More generally, it decouples 'callable from SQL' from the type system; today
that can only be expressed through pseudo-types.
5. It has the potential to be later extended to other support functions, e.g.
opclass support like btint4cmp, if a type's author wants to hide them.
6. Extensions could define functions with limited exposure to the users. Great
simplification for me personally (suppose that needs a CREATE FUNCTION clause
and other stuff).
7. \df could filter such functions out by default.

Having written that, I recalled a similar issue while writing prosupport
functions: I need to remember that someone might add my prosupport to something
else I originally planned. It is an unrelated discussion, of course, but maybe
we need a more general mechanism than a boolean. Imagine a mask of allowed call
contexts, declared in SQL similar to Oracle’s ACCESSIBLE BY clause:

CREATE FUNCTION ... CALLABLE FROM (sql, aggregate)

The core would check it at binding time (parser for plain SQL calls, CREATE
AGGREGATE/TRIGGER/OPERATOR CLASS etc. for the rest), and a function whose mask
excludes 'sql' could drop its defensive checks entirely.

-- 
regards, Andrei Lepikhov,
pgEdge


Reply via email to