Skip to content
Advertisement

Starting from a column type, how to find supported aggregations in Postgres?

I’m trying to figure out from a column type, which aggregates the data type supports. There’s a lot of variety amongst types, just a sample below (some of these support more aggregates, of course):

I’ve been thrashing around in the system catalogs and views, but haven’t found what I’m after. (See “thrashing around.”) I’ve poked at pg_type, pg_aggregate, pg_operator, and a few more.

Is there a straightforward way to start from a column type and gather all supported aggregates?

For background, I’m writing a client-side cross-tab code generator, and the UX is better when the tool automatically prevents you from selecting an aggregation that’s not supported. I’ve hacked in some hard-coded rules for now, but would like to improve the system.

We’re on Postgres 11.4.

Advertisement

Answer

A plain list of available aggregate functions can be based on pg_proc like this:

Or with separate function name and arguments:

pg_proc.prokind replaces proisagg in Postgres 11. In Postgres 10 or older use:

Related:

To get a list of available functions for every data type (your question), start with:

db<>fiddle here

Just a start. Some of the arguments are just “direct” (non-aggregated) (That’s also why some functions are listed multiple times – due to those additional non-aggregate columns, example string_agg). And there are special cases for “ordered-set” and “hypothetical-set” aggregates. See the columns aggkind and aggnumdirectargs of the additional system catalog pg_aggregate. (You may want to exclude the exotic special cases for starters …)

And many types have an implicit cast to one of the types listed by the query. Prominent example string_agg() works with varchar, too, but it’s only listed for text above. You can extend the query with information from pg_cast to get the full picture.

Plus, some aggregates work for pseudo types "any", anyarray etc. You’ll want to factor those in for every applicable data type.

The complication of multiple aliases for the same data type names can be eliminated easily, though: cast to regtype to get canonical names. Or use pg_typeof() which returns standard names. Related:

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement