]> granicus.if.org Git - postgresql/commitdiff
Clean up memory leakage in find_inheritors() by using pg_list lists
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 7 Dec 1999 04:09:39 +0000 (04:09 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 7 Dec 1999 04:09:39 +0000 (04:09 +0000)
(which are palloc'd) instead of DLLists (which are malloc'd).  Not very
significant, since this routine seldom has anything useful to do, but
a leak is a leak...

src/backend/parser/parse_func.c

index 8949ae314043c9faa8d50247ba752229c29ff1b0..aafa4e4c9cb057a25113e61b34fa1f2a3b05656b 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.62 1999/11/22 17:56:21 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.63 1999/12/07 04:09:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,9 +21,9 @@
 #include "catalog/pg_aggregate.h"
 #include "catalog/pg_inherits.h"
 #include "catalog/pg_proc.h"
-#include "lib/dllist.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
+#include "nodes/pg_list.h"
 #include "nodes/relation.h"
 #include "parser/parse_agg.h"
 #include "parser/parse_coerce.h"
@@ -70,11 +70,6 @@ static Oid   agg_select_candidate(Oid typeid, CandidateList candidates);
 
 #define ISCOMPLEX(type) (typeidTypeRelid(type) ? true : false)
 
-typedef struct _SuperQE
-{
-       Oid                     sqe_relid;
-} SuperQE;
-
 /*
  ** ParseNestedFuncOrColumn
  **    Given a nested dot expression (i.e. (relation func ... attr), build up
@@ -1078,39 +1073,34 @@ argtype_inherit(int nargs, Oid *oid_array)
 static int
 find_inheritors(Oid relid, Oid **supervec)
 {
-       Oid                *relidvec;
        Relation        inhrel;
        HeapScanDesc inhscan;
        ScanKeyData skey;
        HeapTuple       inhtup;
-       TupleDesc       inhtupdesc;
+       Oid                *relidvec;
        int                     nvisited;
-       SuperQE    *qentry,
-                          *vnode;
-       Dllist     *visited,
+       List       *visited,
                           *queue;
-       Dlelem     *qe,
-                          *elt;
-
-       Relation        rd;
-       Datum           d;
+       List       *elt;
        bool            newrelid;
-       char            isNull;
 
        nvisited = 0;
-       queue = DLNewList();
-       visited = DLNewList();
-
+       queue = NIL;
+       visited = NIL;
 
        inhrel = heap_openr(InheritsRelationName, AccessShareLock);
-       inhtupdesc = RelationGetDescr(inhrel);
 
        /*
         * Use queue to do a breadth-first traversal of the inheritance graph
-        * from the relid supplied up to the root.
+        * from the relid supplied up to the root.  At the top of the loop,
+        * relid is the OID of the reltype to check next, queue is the list
+        * of pending rels to check after this one, and visited is the list
+        * of relids we need to output.
         */
        do
        {
+               /* find all types this relid inherits from, and add them to queue */
+
                ScanKeyEntryInitialize(&skey, 0x0, Anum_pg_inherits_inhrelid,
                                                           F_OIDEQ,
                                                           ObjectIdGetDatum(relid));
@@ -1119,55 +1109,33 @@ find_inheritors(Oid relid, Oid **supervec)
 
                while (HeapTupleIsValid(inhtup = heap_getnext(inhscan, 0)))
                {
-                       qentry = (SuperQE *) palloc(sizeof(SuperQE));
+                       Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inhtup);
 
-                       d = fastgetattr(inhtup, Anum_pg_inherits_inhparent,
-                                                       inhtupdesc, &isNull);
-                       qentry->sqe_relid = DatumGetObjectId(d);
-
-                       /* put this one on the queue */
-                       DLAddTail(queue, DLNewElem(qentry));
+                       queue = lappendi(queue, inh->inhparent);
                }
 
                heap_endscan(inhscan);
 
                /* pull next unvisited relid off the queue */
-               do
-               {
-                       qe = DLRemHead(queue);
-                       qentry = qe ? (SuperQE *) DLE_VAL(qe) : NULL;
-
-                       if (qentry == (SuperQE *) NULL)
-                               break;
 
-                       relid = qentry->sqe_relid;
-                       newrelid = true;
-
-                       for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt))
+               newrelid = false;
+               while (queue != NIL)
+               {
+                       relid = lfirsti(queue);
+                       queue = lnext(queue);
+                       if (! intMember(relid, visited))
                        {
-                               vnode = (SuperQE *) DLE_VAL(elt);
-                               if (vnode && (qentry->sqe_relid == vnode->sqe_relid))
-                               {
-                                       newrelid = false;
-                                       break;
-                               }
+                               newrelid = true;
+                               break;
                        }
-               } while (!newrelid);
+               }
 
-               if (qentry != (SuperQE *) NULL)
+               if (newrelid)
                {
-                       /* save the type id, rather than the relation id */
-                       rd = heap_open(qentry->sqe_relid, NoLock);
-                       if (! RelationIsValid(rd))
-                               elog(ERROR, "Relid %u does not exist", qentry->sqe_relid);
-                       qentry->sqe_relid = typeTypeId(typenameType(RelationGetRelationName(rd)));
-                       heap_close(rd, NoLock);
-
-                       DLAddTail(visited, qe);
-
+                       visited = lappendi(visited, relid);
                        nvisited++;
                }
-       } while (qentry != (SuperQE *) NULL);
+       } while (newrelid);
 
        heap_close(inhrel, AccessShareLock);
 
@@ -1176,16 +1144,29 @@ find_inheritors(Oid relid, Oid **supervec)
                relidvec = (Oid *) palloc(nvisited * sizeof(Oid));
                *supervec = relidvec;
 
-               for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt))
+               foreach(elt, visited)
                {
-                       vnode = (SuperQE *) DLE_VAL(elt);
-                       *relidvec++ = vnode->sqe_relid;
-               }
+                       /* return the type id, rather than the relation id */
+                       Relation        rd;
+                       Oid                     trelid;
 
+                       relid = lfirsti(elt);
+                       rd = heap_open(relid, NoLock);
+                       if (! RelationIsValid(rd))
+                               elog(ERROR, "Relid %u does not exist", relid);
+                       trelid = typeTypeId(typenameType(RelationGetRelationName(rd)));
+                       heap_close(rd, NoLock);
+                       *relidvec++ = trelid;
+               }
        }
        else
                *supervec = (Oid *) NULL;
 
+       freeList(visited);
+       /* there doesn't seem to be any equally easy way to release the queue
+        * list cells, but since they're palloc'd space it's not critical.
+        */
+
        return nvisited;
 }