aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/prep/prepagg.c
diff options
context:
space:
mode:
authorDavid Rowley <drowley@postgresql.org>2023-01-23 17:35:01 +1300
committerDavid Rowley <drowley@postgresql.org>2023-01-23 17:35:01 +1300
commit16fd03e956540d1b47b743f6a84f37c54ac93dd4 (patch)
tree5d4e04184fcc5e119b92d48529b60bc160f99633 /src/backend/optimizer/prep/prepagg.c
parent5a3a95385bd5a8f1a4fd50545b7efe9338581899 (diff)
downloadpostgresql-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.c28
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;