aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/setrefs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/setrefs.c')
-rw-r--r--src/backend/optimizer/plan/setrefs.c68
1 files changed, 42 insertions, 26 deletions
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index c63758cb2b7..16e5537f7f9 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -2181,22 +2181,14 @@ fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context)
if (IsA(node, Aggref))
{
Aggref *aggref = (Aggref *) node;
+ Param *aggparam;
/* See if the Aggref should be replaced by a Param */
- if (context->root->minmax_aggs != NIL &&
- list_length(aggref->args) == 1)
+ aggparam = find_minmax_agg_replacement_param(context->root, aggref);
+ if (aggparam != NULL)
{
- TargetEntry *curTarget = (TargetEntry *) linitial(aggref->args);
- ListCell *lc;
-
- foreach(lc, context->root->minmax_aggs)
- {
- MinMaxAggInfo *mminfo = (MinMaxAggInfo *) lfirst(lc);
-
- if (mminfo->aggfnoid == aggref->aggfnoid &&
- equal(mminfo->target, curTarget->expr))
- return (Node *) copyObject(mminfo->param);
- }
+ /* Make a copy of the Param for paranoia's sake */
+ return (Node *) copyObject(aggparam);
}
/* If no match, just fall through to process it normally */
}
@@ -3225,22 +3217,14 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
if (IsA(node, Aggref))
{
Aggref *aggref = (Aggref *) node;
+ Param *aggparam;
/* See if the Aggref should be replaced by a Param */
- if (context->root->minmax_aggs != NIL &&
- list_length(aggref->args) == 1)
+ aggparam = find_minmax_agg_replacement_param(context->root, aggref);
+ if (aggparam != NULL)
{
- TargetEntry *curTarget = (TargetEntry *) linitial(aggref->args);
- ListCell *lc;
-
- foreach(lc, context->root->minmax_aggs)
- {
- MinMaxAggInfo *mminfo = (MinMaxAggInfo *) lfirst(lc);
-
- if (mminfo->aggfnoid == aggref->aggfnoid &&
- equal(mminfo->target, curTarget->expr))
- return (Node *) copyObject(mminfo->param);
- }
+ /* Make a copy of the Param for paranoia's sake */
+ return (Node *) copyObject(aggparam);
}
/* If no match, just fall through to process it normally */
}
@@ -3395,6 +3379,38 @@ set_windowagg_runcondition_references(PlannerInfo *root,
return newlist;
}
+/*
+ * find_minmax_agg_replacement_param
+ * If the given Aggref is one that we are optimizing into a subquery
+ * (cf. planagg.c), then return the Param that should replace it.
+ * Else return NULL.
+ *
+ * This is exported so that SS_finalize_plan can use it before setrefs.c runs.
+ * Note that it will not find anything until we have built a Plan from a
+ * MinMaxAggPath, as root->minmax_aggs will never be filled otherwise.
+ */
+Param *
+find_minmax_agg_replacement_param(PlannerInfo *root, Aggref *aggref)
+{
+ if (root->minmax_aggs != NIL &&
+ list_length(aggref->args) == 1)
+ {
+ TargetEntry *curTarget = (TargetEntry *) linitial(aggref->args);
+ ListCell *lc;
+
+ foreach(lc, root->minmax_aggs)
+ {
+ MinMaxAggInfo *mminfo = (MinMaxAggInfo *) lfirst(lc);
+
+ if (mminfo->aggfnoid == aggref->aggfnoid &&
+ equal(mminfo->target, curTarget->expr))
+ return mminfo->param;
+ }
+ }
+ return NULL;
+}
+
+
/*****************************************************************************
* QUERY DEPENDENCY MANAGEMENT
*****************************************************************************/