Bruce Momjian wrote:
Has this been addressed?
Tom Lane wrote:
The reason we could safely list_free inside transformInsertRow is that
we know all its callers have just built the passed-in list and so there
are no other pointers to it. That doesn't apply in the general case of
grammar output.
After another look, even in this case there could be other pointers.
Starting around line 667 of analyze.c:
8<------------------
foreach(lc, selectQuery->targetList)
{
TargetEntry *tle = (TargetEntry *) lfirst(lc);
Expr *expr;
if (tle->resjunk)
continue;
if (tle->expr &&
(IsA(tle->expr, Const) ||IsA(tle->expr, Param)) &&
exprType((Node *) tle->expr) == UNKNOWNOID)
expr = tle->expr;
else
expr = (Expr *) makeVar(rtr->rtindex,
tle->resno,
exprType((Node *) tle->expr),
exprTypmod((Node *) tle->expr),
0);
exprList = lappend(exprList, expr);
}
/* Prepare row for assignment to target table */
exprList = transformInsertRow(pstate, exprList,
stmt->cols,
icolumns, attrnos);
8<------------------
So in the UNKNOWNOID case, it wouldn't be safe to free the node after
transformation because it originates in the grammar output. The *only*
safe thing to free up would be a the input exprList itself. Not much to
be saved there.
My advice is to get that low-hanging fruit
in transformInsertRow and leave the other ideas for 8.3.
This one case doesn't provide that much memory savings by itself anyway.
I guess we'll just live with it until we can come up with a safe way to
free grammar output.
Joe
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?
http://www.postgresql.org/docs/faq