summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r--src/backend/optimizer/util/clauses.c12
-rw-r--r--src/backend/optimizer/util/pathnode.c4
-rw-r--r--src/backend/optimizer/util/tlist.c11
3 files changed, 19 insertions, 8 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index d80dfbe5c9..c615717dea 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -464,11 +464,15 @@ aggregates_allow_partial_walker(Node *node, partial_agg_context *context)
}
/*
- * If we find any aggs with an internal transtype then we must ensure
- * that pointers to aggregate states are not passed to other processes;
- * therefore, we set the maximum allowed type to PAT_INTERNAL_ONLY.
+ * If we find any aggs with an internal transtype then we must check
+ * that these have a serialization type, serialization func and
+ * deserialization func; otherwise, we set the maximum allowed type to
+ * PAT_INTERNAL_ONLY.
*/
- if (aggform->aggtranstype == INTERNALOID)
+ if (aggform->aggtranstype == INTERNALOID &&
+ (!OidIsValid(aggform->aggserialtype) ||
+ !OidIsValid(aggform->aggserialfn) ||
+ !OidIsValid(aggform->aggdeserialfn)))
context->allowedtype = PAT_INTERNAL_ONLY;
ReleaseSysCache(aggTuple);
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 16b34fcf46..89cae793ca 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -2433,7 +2433,8 @@ create_agg_path(PlannerInfo *root,
const AggClauseCosts *aggcosts,
double numGroups,
bool combineStates,
- bool finalizeAggs)
+ bool finalizeAggs,
+ bool serialStates)
{
AggPath *pathnode = makeNode(AggPath);
@@ -2458,6 +2459,7 @@ create_agg_path(PlannerInfo *root,
pathnode->qual = qual;
pathnode->finalizeAggs = finalizeAggs;
pathnode->combineStates = combineStates;
+ pathnode->serialStates = serialStates;
cost_agg(&pathnode->path, root,
aggstrategy, aggcosts,
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index cd421b1463..4c8c83da80 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -756,8 +756,8 @@ apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target)
* apply_partialaggref_adjustment
* Convert PathTarget to be suitable for a partial aggregate node. We simply
* adjust any Aggref nodes found in the target and set the aggoutputtype to
- * the aggtranstype. This allows exprType() to return the actual type that
- * will be produced.
+ * the aggtranstype or aggserialtype. This allows exprType() to return the
+ * actual type that will be produced.
*
* Note: We expect 'target' to be a flat target list and not have Aggrefs burried
* within other expressions.
@@ -785,7 +785,12 @@ apply_partialaggref_adjustment(PathTarget *target)
aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple);
newaggref = (Aggref *) copyObject(aggref);
- newaggref->aggoutputtype = aggform->aggtranstype;
+
+ /* use the serialization type, if one exists */
+ if (OidIsValid(aggform->aggserialtype))
+ newaggref->aggoutputtype = aggform->aggserialtype;
+ else
+ newaggref->aggoutputtype = aggform->aggtranstype;
lfirst(lc) = newaggref;