Skip to content

Commit 04fa5ca

Browse files
committed
Clean up memory leakage in find_inheritors() by using pg_list lists
(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...
1 parent 5ad4034 commit 04fa5ca

File tree

1 file changed

+44
-63
lines changed

1 file changed

+44
-63
lines changed

src/backend/parser/parse_func.c

Lines changed: 44 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.62 1999/11/22 17:56:21 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.63 1999/12/07 04:09:39 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -21,9 +21,9 @@
2121
#include "catalog/pg_aggregate.h"
2222
#include "catalog/pg_inherits.h"
2323
#include "catalog/pg_proc.h"
24-
#include "lib/dllist.h"
2524
#include "miscadmin.h"
2625
#include "nodes/makefuncs.h"
26+
#include "nodes/pg_list.h"
2727
#include "nodes/relation.h"
2828
#include "parser/parse_agg.h"
2929
#include "parser/parse_coerce.h"
@@ -70,11 +70,6 @@ static Oid agg_select_candidate(Oid typeid, CandidateList candidates);
7070

7171
#define ISCOMPLEX(type) (typeidTypeRelid(type) ? true : false)
7272

73-
typedef struct _SuperQE
74-
{
75-
Oid sqe_relid;
76-
} SuperQE;
77-
7873
/*
7974
** ParseNestedFuncOrColumn
8075
** Given a nested dot expression (i.e. (relation func ... attr), build up
@@ -1078,39 +1073,34 @@ argtype_inherit(int nargs, Oid *oid_array)
10781073
static int
10791074
find_inheritors(Oid relid, Oid **supervec)
10801075
{
1081-
Oid *relidvec;
10821076
Relation inhrel;
10831077
HeapScanDesc inhscan;
10841078
ScanKeyData skey;
10851079
HeapTuple inhtup;
1086-
TupleDesc inhtupdesc;
1080+
Oid *relidvec;
10871081
int nvisited;
1088-
SuperQE *qentry,
1089-
*vnode;
1090-
Dllist *visited,
1082+
List *visited,
10911083
*queue;
1092-
Dlelem *qe,
1093-
*elt;
1094-
1095-
Relation rd;
1096-
Datum d;
1084+
List *elt;
10971085
bool newrelid;
1098-
char isNull;
10991086

11001087
nvisited = 0;
1101-
queue = DLNewList();
1102-
visited = DLNewList();
1103-
1088+
queue = NIL;
1089+
visited = NIL;
11041090

11051091
inhrel = heap_openr(InheritsRelationName, AccessShareLock);
1106-
inhtupdesc = RelationGetDescr(inhrel);
11071092

11081093
/*
11091094
* Use queue to do a breadth-first traversal of the inheritance graph
1110-
* from the relid supplied up to the root.
1095+
* from the relid supplied up to the root. At the top of the loop,
1096+
* relid is the OID of the reltype to check next, queue is the list
1097+
* of pending rels to check after this one, and visited is the list
1098+
* of relids we need to output.
11111099
*/
11121100
do
11131101
{
1102+
/* find all types this relid inherits from, and add them to queue */
1103+
11141104
ScanKeyEntryInitialize(&skey, 0x0, Anum_pg_inherits_inhrelid,
11151105
F_OIDEQ,
11161106
ObjectIdGetDatum(relid));
@@ -1119,55 +1109,33 @@ find_inheritors(Oid relid, Oid **supervec)
11191109

11201110
while (HeapTupleIsValid(inhtup = heap_getnext(inhscan, 0)))
11211111
{
1122-
qentry = (SuperQE *) palloc(sizeof(SuperQE));
1112+
Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inhtup);
11231113

1124-
d = fastgetattr(inhtup, Anum_pg_inherits_inhparent,
1125-
inhtupdesc, &isNull);
1126-
qentry->sqe_relid = DatumGetObjectId(d);
1127-
1128-
/* put this one on the queue */
1129-
DLAddTail(queue, DLNewElem(qentry));
1114+
queue = lappendi(queue, inh->inhparent);
11301115
}
11311116

11321117
heap_endscan(inhscan);
11331118

11341119
/* pull next unvisited relid off the queue */
1135-
do
1136-
{
1137-
qe = DLRemHead(queue);
1138-
qentry = qe ? (SuperQE *) DLE_VAL(qe) : NULL;
1139-
1140-
if (qentry == (SuperQE *) NULL)
1141-
break;
11421120

1143-
relid = qentry->sqe_relid;
1144-
newrelid = true;
1145-
1146-
for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt))
1121+
newrelid = false;
1122+
while (queue != NIL)
1123+
{
1124+
relid = lfirsti(queue);
1125+
queue = lnext(queue);
1126+
if (! intMember(relid, visited))
11471127
{
1148-
vnode = (SuperQE *) DLE_VAL(elt);
1149-
if (vnode && (qentry->sqe_relid == vnode->sqe_relid))
1150-
{
1151-
newrelid = false;
1152-
break;
1153-
}
1128+
newrelid = true;
1129+
break;
11541130
}
1155-
} while (!newrelid);
1131+
}
11561132

1157-
if (qentry != (SuperQE *) NULL)
1133+
if (newrelid)
11581134
{
1159-
/* save the type id, rather than the relation id */
1160-
rd = heap_open(qentry->sqe_relid, NoLock);
1161-
if (! RelationIsValid(rd))
1162-
elog(ERROR, "Relid %u does not exist", qentry->sqe_relid);
1163-
qentry->sqe_relid = typeTypeId(typenameType(RelationGetRelationName(rd)));
1164-
heap_close(rd, NoLock);
1165-
1166-
DLAddTail(visited, qe);
1167-
1135+
visited = lappendi(visited, relid);
11681136
nvisited++;
11691137
}
1170-
} while (qentry != (SuperQE *) NULL);
1138+
} while (newrelid);
11711139

11721140
heap_close(inhrel, AccessShareLock);
11731141

@@ -1176,16 +1144,29 @@ find_inheritors(Oid relid, Oid **supervec)
11761144
relidvec = (Oid *) palloc(nvisited * sizeof(Oid));
11771145
*supervec = relidvec;
11781146

1179-
for (elt = DLGetHead(visited); elt; elt = DLGetSucc(elt))
1147+
foreach(elt, visited)
11801148
{
1181-
vnode = (SuperQE *) DLE_VAL(elt);
1182-
*relidvec++ = vnode->sqe_relid;
1183-
}
1149+
/* return the type id, rather than the relation id */
1150+
Relation rd;
1151+
Oid trelid;
11841152

1153+
relid = lfirsti(elt);
1154+
rd = heap_open(relid, NoLock);
1155+
if (! RelationIsValid(rd))
1156+
elog(ERROR, "Relid %u does not exist", relid);
1157+
trelid = typeTypeId(typenameType(RelationGetRelationName(rd)));
1158+
heap_close(rd, NoLock);
1159+
*relidvec++ = trelid;
1160+
}
11851161
}
11861162
else
11871163
*supervec = (Oid *) NULL;
11881164

1165+
freeList(visited);
1166+
/* there doesn't seem to be any equally easy way to release the queue
1167+
* list cells, but since they're palloc'd space it's not critical.
1168+
*/
1169+
11891170
return nvisited;
11901171
}
11911172

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy