Repair memory leaks that caused CacheCxt to grow without bound. We
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 21 May 2000 02:28:55 +0000 (02:28 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 21 May 2000 02:28:55 +0000 (02:28 +0000)
really ought to fix relcache entry construction so that it does not
do so much with CurrentMemoryContext = CacheCxt.  As is, relatively
harmless leaks in either sequential or index scanning translate to
permanent leaks if they occur when called from relcache build.
For the moment, however, the path of least resistance is to repair
all such leaks...

src/backend/access/heap/heapam.c
src/backend/utils/cache/relcache.c

index 29d6c9e0f9ec0208fb191a52eed1f75252f5edc9..e7a549d410b834f83f433f176c4d76e24638719f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.67 2000/04/12 17:14:45 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.68 2000/05/21 02:28:54 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -766,6 +766,9 @@ heap_endscan(HeapScanDesc scan)
     */
    RelationDecrementReferenceCount(scan->rs_rd);
 
+   if (scan->rs_key)
+       pfree(scan->rs_key);
+
    pfree(scan);
 }
 
index 41fcdf1d2734b48766afe5fbb08f4a924245889f..b9e86d905ecb238617bb6b11a57aa834d005f7c0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.95 2000/04/12 17:15:54 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.96 2000/05/21 02:28:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -245,6 +245,9 @@ static bool criticalRelcacheBuild = false;
  *     this is used by RelationBuildDesc to find a pg_class
  *     tuple matching either a relation name or a relation id
  *     as specified in buildinfo.
+ *
+ *     NB: the returned tuple has been copied into palloc'd storage
+ *     and must eventually be freed with heap_freetuple.
  * --------------------------------
  */
 static HeapTuple
@@ -356,6 +359,8 @@ scan_pg_rel_ind(RelationBuildDescInfo buildinfo)
 
    heap_close(pg_class_desc, AccessShareLock);
 
+   /* The xxxIndexScan routines will have returned a palloc'd tuple. */
+
    return return_tuple;
 }
 
@@ -519,9 +524,9 @@ build_tupdesc_seq(RelationBuildDescInfo buildinfo,
            relation->rd_att->attrs[attp->attnum - 1] =
                (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
 
-           memmove((char *) (relation->rd_att->attrs[attp->attnum - 1]),
-                   (char *) attp,
-                   ATTRIBUTE_TUPLE_SIZE);
+           memcpy((char *) (relation->rd_att->attrs[attp->attnum - 1]),
+                  (char *) attp,
+                  ATTRIBUTE_TUPLE_SIZE);
            need--;
            /* Update if this attribute have a constraint */
            if (attp->attnotnull)
@@ -571,11 +576,6 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
    int         ndef = 0;
    int         i;
 
-#ifdef _DROP_COLUMN_HACK__
-   bool        columnDropped;
-
-#endif  /* _DROP_COLUMN_HACK__ */
-
    constr->has_not_null = false;
 
    attrel = heap_openr(AttributeRelationName, AccessShareLock);
@@ -583,14 +583,15 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
    for (i = 1; i <= relation->rd_rel->relnatts; i++)
    {
 #ifdef _DROP_COLUMN_HACK__
-       columnDropped = false;
+       bool        columnDropped = false;
 #endif  /* _DROP_COLUMN_HACK__ */
+
        atttup = (HeapTuple) AttributeRelidNumIndexScan(attrel,
                                          RelationGetRelid(relation), i);
 
        if (!HeapTupleIsValid(atttup))
-#ifdef _DROP_COLUMN_HACK__
        {
+#ifdef _DROP_COLUMN_HACK__
            atttup = (HeapTuple) AttributeRelidNumIndexScan(attrel,
                    RelationGetRelid(relation), DROPPED_COLUMN_INDEX(i));
            if (!HeapTupleIsValid(atttup))
@@ -599,21 +600,24 @@ build_tupdesc_ind(RelationBuildDescInfo buildinfo,
                     RelationGetRelationName(relation));
 #ifdef _DROP_COLUMN_HACK__
            columnDropped = true;
-       }
 #endif  /* _DROP_COLUMN_HACK__ */
-       attp = (Form_pg_attribute) GETSTRUCT(atttup);
+       }
 
-       relation->rd_att->attrs[i - 1] =
+       relation->rd_att->attrs[i - 1] = attp =
            (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
 
-       memmove((char *) (relation->rd_att->attrs[i - 1]),
-               (char *) attp,
-               ATTRIBUTE_TUPLE_SIZE);
+       memcpy((char *) attp,
+              (char *) (Form_pg_attribute) GETSTRUCT(atttup),
+              ATTRIBUTE_TUPLE_SIZE);
+
+       /* don't forget to free the tuple returned from xxxIndexScan */
+       heap_freetuple(atttup);
 
 #ifdef _DROP_COLUMN_HACK__
        if (columnDropped)
            continue;
 #endif  /* _DROP_COLUMN_HACK__ */
+
        /* Update if this attribute have a constraint */
        if (attp->attnotnull)
            constr->has_not_null = true;
@@ -1117,12 +1121,9 @@ formrdesc(char *relationName,
    for (i = 0; i < natts; i++)
    {
        relation->rd_att->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
-
-       MemSet((char *) relation->rd_att->attrs[i], 0,
+       memcpy((char *) relation->rd_att->attrs[i],
+              (char *) &att[i],
               ATTRIBUTE_TUPLE_SIZE);
-       memmove((char *) relation->rd_att->attrs[i],
-               (char *) &att[i],
-               ATTRIBUTE_TUPLE_SIZE);
    }
 
    /* ----------------