@@ -47,8 +47,6 @@ typedef struct OSAPerQueryState
47
47
Aggref * aggref ;
48
48
/* Memory context containing this struct and other per-query data: */
49
49
MemoryContext qcontext ;
50
- /* Memory context containing per-group data: */
51
- MemoryContext gcontext ;
52
50
53
51
/* These fields are used only when accumulating tuples: */
54
52
@@ -86,6 +84,8 @@ typedef struct OSAPerGroupState
86
84
{
87
85
/* Link to the per-query state for this aggregate: */
88
86
OSAPerQueryState * qstate ;
87
+ /* Memory context containing per-group data: */
88
+ MemoryContext gcontext ;
89
89
/* Sort object we're accumulating data in: */
90
90
Tuplesortstate * sortstate ;
91
91
/* Number of normal rows inserted into sortstate: */
@@ -103,8 +103,17 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
103
103
{
104
104
OSAPerGroupState * osastate ;
105
105
OSAPerQueryState * qstate ;
106
+ MemoryContext gcontext ;
106
107
MemoryContext oldcontext ;
107
108
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
+
108
117
/*
109
118
* We keep a link to the per-query state in fn_extra; if it's not there,
110
119
* create it, and do the per-query setup we need.
@@ -114,17 +123,10 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
114
123
{
115
124
Aggref * aggref ;
116
125
MemoryContext qcontext ;
117
- MemoryContext gcontext ;
118
126
List * sortlist ;
119
127
int numSortCols ;
120
128
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 */
128
130
aggref = AggGetAggref (fcinfo );
129
131
if (!aggref )
130
132
elog (ERROR , "ordered-set aggregate called in non-aggregate context" );
@@ -142,7 +144,6 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
142
144
qstate = (OSAPerQueryState * ) palloc0 (sizeof (OSAPerQueryState ));
143
145
qstate -> aggref = aggref ;
144
146
qstate -> qcontext = qcontext ;
145
- qstate -> gcontext = gcontext ;
146
147
147
148
/* Extract the sort information */
148
149
sortlist = aggref -> aggorder ;
@@ -259,10 +260,11 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
259
260
}
260
261
261
262
/* Now build the stuff we need in group-lifespan context */
262
- oldcontext = MemoryContextSwitchTo (qstate -> gcontext );
263
+ oldcontext = MemoryContextSwitchTo (gcontext );
263
264
264
265
osastate = (OSAPerGroupState * ) palloc (sizeof (OSAPerGroupState ));
265
266
osastate -> qstate = qstate ;
267
+ osastate -> gcontext = gcontext ;
266
268
267
269
/* Initialize tuplesort object */
268
270
if (use_tuples )
@@ -282,7 +284,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
282
284
283
285
osastate -> number_of_rows = 0 ;
284
286
285
- /* Now register a shutdown callback to clean things up */
287
+ /* Now register a shutdown callback to clean things up at end of group */
286
288
AggRegisterCallback (fcinfo ,
287
289
ordered_set_shutdown ,
288
290
PointerGetDatum (osastate ));
0 commit comments