Skip to content

Commit ecd6579

Browse files
committed
Don't cache per-group context across the whole query in orderedsetaggs.c.
Although nodeAgg.c currently uses the same per-group memory context for all groups of a query, that might change in future. Avoid assuming it. This costs us an extra AggCheckCallContext() call per group, but that's pretty cheap and is probably good from a safety standpoint anyway. Back-patch to 9.4 in case any third-party code copies this logic. Andrew Gierth
1 parent 6f5034e commit ecd6579

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

src/backend/utils/adt/orderedsetaggs.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ typedef struct OSAPerQueryState
4747
Aggref *aggref;
4848
/* Memory context containing this struct and other per-query data: */
4949
MemoryContext qcontext;
50-
/* Memory context containing per-group data: */
51-
MemoryContext gcontext;
5250

5351
/* These fields are used only when accumulating tuples: */
5452

@@ -86,6 +84,8 @@ typedef struct OSAPerGroupState
8684
{
8785
/* Link to the per-query state for this aggregate: */
8886
OSAPerQueryState *qstate;
87+
/* Memory context containing per-group data: */
88+
MemoryContext gcontext;
8989
/* Sort object we're accumulating data in: */
9090
Tuplesortstate *sortstate;
9191
/* Number of normal rows inserted into sortstate: */
@@ -103,8 +103,17 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
103103
{
104104
OSAPerGroupState *osastate;
105105
OSAPerQueryState *qstate;
106+
MemoryContext gcontext;
106107
MemoryContext oldcontext;
107108

109+
/*
110+
* Check we're called as aggregate (and not a window function), and get
111+
* the Agg node's group-lifespan context (which might change from group to
112+
* group, so we shouldn't cache it in the per-query state).
113+
*/
114+
if (AggCheckCallContext(fcinfo, &gcontext) != AGG_CONTEXT_AGGREGATE)
115+
elog(ERROR, "ordered-set aggregate called in non-aggregate context");
116+
108117
/*
109118
* We keep a link to the per-query state in fn_extra; if it's not there,
110119
* create it, and do the per-query setup we need.
@@ -114,17 +123,10 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
114123
{
115124
Aggref *aggref;
116125
MemoryContext qcontext;
117-
MemoryContext gcontext;
118126
List *sortlist;
119127
int numSortCols;
120128

121-
/*
122-
* Check we're called as aggregate (and not a window function), and
123-
* get the Agg node's group-lifespan context
124-
*/
125-
if (AggCheckCallContext(fcinfo, &gcontext) != AGG_CONTEXT_AGGREGATE)
126-
elog(ERROR, "ordered-set aggregate called in non-aggregate context");
127-
/* Need the Aggref as well */
129+
/* Get the Aggref so we can examine aggregate's arguments */
128130
aggref = AggGetAggref(fcinfo);
129131
if (!aggref)
130132
elog(ERROR, "ordered-set aggregate called in non-aggregate context");
@@ -142,7 +144,6 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
142144
qstate = (OSAPerQueryState *) palloc0(sizeof(OSAPerQueryState));
143145
qstate->aggref = aggref;
144146
qstate->qcontext = qcontext;
145-
qstate->gcontext = gcontext;
146147

147148
/* Extract the sort information */
148149
sortlist = aggref->aggorder;
@@ -259,10 +260,11 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
259260
}
260261

261262
/* Now build the stuff we need in group-lifespan context */
262-
oldcontext = MemoryContextSwitchTo(qstate->gcontext);
263+
oldcontext = MemoryContextSwitchTo(gcontext);
263264

264265
osastate = (OSAPerGroupState *) palloc(sizeof(OSAPerGroupState));
265266
osastate->qstate = qstate;
267+
osastate->gcontext = gcontext;
266268

267269
/* Initialize tuplesort object */
268270
if (use_tuples)
@@ -282,7 +284,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
282284

283285
osastate->number_of_rows = 0;
284286

285-
/* Now register a shutdown callback to clean things up */
287+
/* Now register a shutdown callback to clean things up at end of group */
286288
AggRegisterCallback(fcinfo,
287289
ordered_set_shutdown,
288290
PointerGetDatum(osastate));

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy