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
