diff options
author | David Rowley <drowley@postgresql.org> | 2023-01-23 17:35:01 +1300 |
---|---|---|
committer | David Rowley <drowley@postgresql.org> | 2023-01-23 17:35:01 +1300 |
commit | 16fd03e956540d1b47b743f6a84f37c54ac93dd4 (patch) | |
tree | 5d4e04184fcc5e119b92d48529b60bc160f99633 /src/backend/parser | |
parent | 5a3a95385bd5a8f1a4fd50545b7efe9338581899 (diff) | |
download | postgresql-16fd03e956540d1b47b743f6a84f37c54ac93dd4.tar.gz postgresql-16fd03e956540d1b47b743f6a84f37c54ac93dd4.zip |
Allow parallel aggregate on string_agg and array_agg
This adds combine, serial and deserial functions for the array_agg() and
string_agg() aggregate functions, thus allowing these aggregates to
partake in partial aggregations. This allows both parallel aggregation to
take place when these aggregates are present and also allows additional
partition-wise aggregation plan shapes to include plans that require
additional aggregation once the partially aggregated results from the
partitions have been combined.
Author: David Rowley
Reviewed-by: Andres Freund, Tomas Vondra, Stephen Frost, Tom Lane
Discussion: https://postgr.es/m/CAKJS1f9sx_6GTcvd6TMuZnNtCh0VhBzhX6FZqw17TgVFH-ga_A@mail.gmail.com
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/parse_agg.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index f7a10460262..caecaaae504 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -14,6 +14,7 @@ */ #include "postgres.h" +#include "access/htup_details.h" #include "catalog/pg_aggregate.h" #include "catalog/pg_constraint.h" #include "catalog/pg_type.h" @@ -28,7 +29,7 @@ #include "rewrite/rewriteManip.h" #include "utils/builtins.h" #include "utils/lsyscache.h" - +#include "utils/syscache.h" typedef struct { @@ -1948,6 +1949,40 @@ resolve_aggregate_transtype(Oid aggfuncid, } /* + * agg_args_support_sendreceive + * Returns true if all non-byval of aggref's arg types have send and + * receive functions. + */ +bool +agg_args_support_sendreceive(Aggref *aggref) +{ + ListCell *lc; + + foreach(lc, aggref->args) + { + HeapTuple typeTuple; + Form_pg_type pt; + TargetEntry *tle = (TargetEntry *) lfirst(lc); + Oid type = exprType((Node *) tle->expr); + + typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type)); + if (!HeapTupleIsValid(typeTuple)) + elog(ERROR, "cache lookup failed for type %u", type); + + pt = (Form_pg_type) GETSTRUCT(typeTuple); + + if (!pt->typbyval && + (!OidIsValid(pt->typsend) || !OidIsValid(pt->typreceive))) + { + ReleaseSysCache(typeTuple); + return false; + } + ReleaseSysCache(typeTuple); + } + return true; +} + +/* * Create an expression tree for the transition function of an aggregate. * This is needed so that polymorphic functions can be used within an * aggregate --- without the expression tree, such functions would not know |