|
55 | 55 | * in either case its value need not be preserved. See int8inc() for an
|
56 | 56 | * example. Notice that advance_transition_function() is coded to avoid a
|
57 | 57 | * data copy step when the previous transition value pointer is returned.
|
| 58 | + * Also, some transition functions make use of the aggcontext to store |
| 59 | + * working state. |
58 | 60 | *
|
59 | 61 | *
|
60 | 62 | * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
61 | 63 | * Portions Copyright (c) 1994, Regents of the University of California
|
62 | 64 | *
|
63 | 65 | * IDENTIFICATION
|
64 |
| - * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.167 2009/06/17 16:05:34 tgl Exp $ |
| 66 | + * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.168 2009/07/23 20:45:27 tgl Exp $ |
65 | 67 | *
|
66 | 68 | *-------------------------------------------------------------------------
|
67 | 69 | */
|
@@ -272,18 +274,6 @@ initialize_aggregates(AggState *aggstate,
|
272 | 274 | work_mem, false);
|
273 | 275 | }
|
274 | 276 |
|
275 |
| - /* |
276 |
| - * If we are reinitializing after a group boundary, we have to free |
277 |
| - * any prior transValue to avoid memory leakage. We must check not |
278 |
| - * only the isnull flag but whether the pointer is NULL; since |
279 |
| - * pergroupstate is initialized with palloc0, the initial condition |
280 |
| - * has isnull = 0 and null pointer. |
281 |
| - */ |
282 |
| - if (!peraggstate->transtypeByVal && |
283 |
| - !pergroupstate->transValueIsNull && |
284 |
| - DatumGetPointer(pergroupstate->transValue) != NULL) |
285 |
| - pfree(DatumGetPointer(pergroupstate->transValue)); |
286 |
| - |
287 | 277 | /*
|
288 | 278 | * (Re)set transValue to the initial value.
|
289 | 279 | *
|
@@ -911,10 +901,15 @@ agg_retrieve_direct(AggState *aggstate)
|
911 | 901 | }
|
912 | 902 |
|
913 | 903 | /*
|
914 |
| - * Clear the per-output-tuple context for each group |
| 904 | + * Clear the per-output-tuple context for each group, as well as |
| 905 | + * aggcontext (which contains any pass-by-ref transvalues of the |
| 906 | + * old group). We also clear any child contexts of the aggcontext; |
| 907 | + * some aggregate functions store working state in such contexts. |
915 | 908 | */
|
916 | 909 | ResetExprContext(econtext);
|
917 | 910 |
|
| 911 | + MemoryContextResetAndDeleteChildren(aggstate->aggcontext); |
| 912 | + |
918 | 913 | /*
|
919 | 914 | * Initialize working state for a new input tuple group
|
920 | 915 | */
|
@@ -1234,7 +1229,8 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
|
1234 | 1229 | * structures and transition values. NOTE: the details of what is stored
|
1235 | 1230 | * in aggcontext and what is stored in the regular per-query memory
|
1236 | 1231 | * context are driven by a simple decision: we want to reset the
|
1237 |
| - * aggcontext in ExecReScanAgg to recover no-longer-wanted space. |
| 1232 | + * aggcontext at group boundaries (if not hashing) and in ExecReScanAgg |
| 1233 | + * to recover no-longer-wanted space. |
1238 | 1234 | */
|
1239 | 1235 | aggstate->aggcontext =
|
1240 | 1236 | AllocSetContextCreate(CurrentMemoryContext,
|
|
0 commit comments