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/optimizer/prep/prepagg.c | |
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/optimizer/prep/prepagg.c')
-rw-r--r-- | src/backend/optimizer/prep/prepagg.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/src/backend/optimizer/prep/prepagg.c b/src/backend/optimizer/prep/prepagg.c index 2d31ad6bed8..806078311c6 100644 --- a/src/backend/optimizer/prep/prepagg.c +++ b/src/backend/optimizer/prep/prepagg.c @@ -305,10 +305,30 @@ preprocess_aggref(Aggref *aggref, PlannerInfo *root) * functions; if not, we can't serialize partial-aggregation * results. */ - else if (transinfo->aggtranstype == INTERNALOID && - (!OidIsValid(transinfo->serialfn_oid) || - !OidIsValid(transinfo->deserialfn_oid))) - root->hasNonSerialAggs = true; + else if (transinfo->aggtranstype == INTERNALOID) + { + + if (!OidIsValid(transinfo->serialfn_oid) || + !OidIsValid(transinfo->deserialfn_oid)) + root->hasNonSerialAggs = true; + + /* + * array_agg_serialize and array_agg_deserialize make use + * of the aggregate non-byval input type's send and + * receive functions. There's a chance that the type + * being aggregated has one or both of these functions + * missing. In this case we must not allow the + * aggregate's serial and deserial functions to be used. + * It would be nice not to have special case this and + * instead provide some sort of supporting function within + * the aggregate to do this, but for now, that seems like + * overkill for this one case. + */ + if ((transinfo->serialfn_oid == F_ARRAY_AGG_SERIALIZE || + transinfo->deserialfn_oid == F_ARRAY_AGG_DESERIALIZE) && + !agg_args_support_sendreceive(aggref)) + root->hasNonSerialAggs = true; + } } } agginfo->transno = transno; |