aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_agg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_agg.c')
-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