]> granicus.if.org Git - postgresql/commitdiff
Repair memory leakage introduced into the non-hashed aggregate case by
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 13 Mar 2004 00:54:10 +0000 (00:54 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 13 Mar 2004 00:54:10 +0000 (00:54 +0000)
7.4 rewrite for hashed aggregate support.  If the transition data type
is pass-by-reference, the transValue must be pfreed when starting a new
group boundary, else we have a one-value-per-group leakage.  Thanks to
Rae Steining for providing a reproducible test case.

src/backend/executor/nodeAgg.c

index cb0a64c42771beb660c1f30a4c2aec1f39dd1711..0a872221276b4da83ef5e1b874e633da9c1beb54 100644 (file)
@@ -45,7 +45,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.118 2004/02/03 17:34:02 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.119 2004/03/13 00:54:10 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -251,6 +251,18 @@ initialize_aggregates(AggState *aggstate,
                                                                          work_mem, false);
                }
 
+               /*
+                * If we are reinitializing after a group boundary, we have to free
+                * any prior transValue to avoid memory leakage.  We must check not
+                * only the isnull flag but whether the pointer is NULL; since
+                * pergroupstate is initialized with palloc0, the initial condition
+                * has isnull = 0 and null pointer.
+                */
+               if (!peraggstate->transtypeByVal &&
+                       !pergroupstate->transValueIsNull &&
+                       DatumGetPointer(pergroupstate->transValue) != NULL)
+                       pfree(DatumGetPointer(pergroupstate->transValue));
+
                /*
                 * (Re)set transValue to the initial value.
                 *
@@ -1472,6 +1484,12 @@ ExecReScanAgg(AggState *node, ExprContext *exprCtxt)
                build_hash_table(node);
                node->table_filled = false;
        }
+       else
+       {
+               /* Reset the per-group state (in particular, mark transvalues null) */
+               MemSet(node->pergroup, 0,
+                          sizeof(AggStatePerGroupData) * node->numaggs);
+       }
 
        /*
         * if chgParam of subnode is not null then plan will be re-scanned by