@@ -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