aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser
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/parser
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/parser')
-rw-r--r--src/backend/parser/parse_agg.c37
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