Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e44964c

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 f688cf5 commit e44964c

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

src/backend/utils/adt/orderedsetaggs.c

+15-13
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)