Re: FmgrInfo allocation patterns (and PL handling as staged programming) - Mailing list pgsql-hackers

From Chapman Flack
Subject Re: FmgrInfo allocation patterns (and PL handling as staged programming)
Date
Msg-id 67F40ACD.7040507@acm.org
Whole thread Raw
In response to Re: FmgrInfo allocation patterns (and PL handling as staged programming)  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: FmgrInfo allocation patterns (and PL handling as staged programming)
List pgsql-hackers
On 04/06/25 13:59, Tom Lane wrote:
> polymorphic arguments: the element type of an anyarray argument can
> change on-the-fly from one call to the next in the same query.  I
> think this is only possible when you're fed pg_stats.most_common_vals
> or one of its sibling columns, but that's enough to be a problem.
> That's why all of our array-munging functions that use fn_extra to
> cache type-dependent state are careful to check the element type
> against the cache every single time.

This was really bumming me out. I thought "what on earth does that do
to the rest of your surrounding query, say if you have anyelement types
in the args or return value also?".

So the answer to that part is easy: if a routine's types include both
anyarray and anyelement (like, say, unnest), it just can't be applied
to one of those statistics columns. An attempt to use it that way in
a query is rejected early, before any attempt to call the routine:

ERROR:  cannot determine element type of "anyarray" argument
STATEMENT:  select unnest(stavalues1) from pg_statistic limit 1;

Now, if you have a routine that uses anyarray but no corresponding
element pseudotype, you are allowed to apply that to a statistics
column. It can even have anyarray as a return/output type also.
When it's applied to a statistics column, here's what my dispatcher sees:

# select foo(stavalues1) from pg_statistic limit 1;

RegProcedure[1255,16861,0]public.foo essentialChecks: checkBody true
RegProcedure[1255,16861,0]public.foo prepare():
inputsTemplate   : [RegType.Unresolved[1247,2277,0]pg_catalog.anyarray]
unresolvedInputs : {0}
outputsTemplate  : [RegType.Unresolved[1247,2277,0]pg_catalog.anyarray]
unresolvedOutputs: {0}

RegProcedure[1255,16861,0]public.foo Template.specialize():
precomputed id   : 39d9314d
inputsDescriptor : [RegType.Unresolved[1247,2277,0]pg_catalog.anyarray]
inputsAreSpread  : false
stableInputs     : {}
outputsDescriptor: [RegType.Unresolved[1247,2277,0]pg_catalog.anyarray]


So the polymorphic type resolution applied at specialize() time
"succeeded", raised no error, and left the pseudotype anyarray
in both the inputs and outputs supposedly-"resolved" results.

That seems to make for a tidy way of recognizing the situation. If
you go to specialize and find anyarray among your supposedly-resolved
call-site types, well, you know you're in Wonderland and can adjust
behavior accordingly.

Regards,
-Chap



pgsql-hackers by date:

Previous
From: Alvaro Herrera
Date:
Subject: Re: Support NOT VALID / VALIDATE constraint options for named NOT NULL constraints
Next
From: Jacob Champion
Date:
Subject: Re: [PoC] Federated Authn/z with OAUTHBEARER