*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.42 2002/11/24 21:52:13 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.43 2002/12/17 01:18:18 tgl Exp $
*
* NOTES
* XXX a few of the following functions are duplicated to handle
* Free the List nodes of a list
* The pointed-to nodes, if any, are NOT freed.
* This works for integer lists too.
- *
*/
void
freeList(List *list)
result = lnext(l);
else
lnext(prev) = lnext(l);
+ pfree(l);
}
return result;
}
result = lnext(l);
else
lnext(prev) = lnext(l);
+ pfree(l);
}
return result;
}
result = lnext(l);
else
lnext(prev) = lnext(l);
+ pfree(l);
}
return result;
}
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.42 2002/12/12 15:49:32 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.43 2002/12/17 01:18:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
newset = NIL;
- foreach(cursetlink, root->equi_key_list)
+ /* cannot use foreach here because of possible lremove */
+ cursetlink = root->equi_key_list;
+ while (cursetlink)
{
List *curset = lfirst(cursetlink);
bool item1here = member(item1, curset);
bool item2here = member(item2, curset);
+ /* must advance cursetlink before lremove possibly pfree's it */
+ cursetlink = lnext(cursetlink);
+
if (item1here || item2here)
{
/*
newset = set_union(newset, curset);
/*
- * Remove old set from equi_key_list. NOTE this does not
- * change lnext(cursetlink), so the foreach loop doesn't
- * break.
+ * Remove old set from equi_key_list.
*/
root->equi_key_list = lremove(curset, root->equi_key_list);
freeList(curset); /* might as well recycle old cons cells */
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.78 2002/12/12 15:49:32 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.79 2002/12/17 01:18:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
do
{
someadded = false;
- foreach(olditem, oldquals)
+ /* cannot use foreach here because of possible lremove */
+ olditem = oldquals;
+ while (olditem)
{
RestrictInfo *oldrinfo = (RestrictInfo *) lfirst(olditem);
Node *oldleft = (Node *) get_leftop(oldrinfo->clause);
Node *oldright = (Node *) get_rightop(oldrinfo->clause);
Node *newguy = NULL;
+ /* must advance olditem before lremove possibly pfree's it */
+ olditem = lnext(olditem);
+
if (member(oldleft, equalvars))
newguy = oldright;
else if (member(oldright, equalvars))
/*
* Remove this qual from list, since we don't need it anymore.
- * Note this doesn't break the foreach() loop, since lremove
- * doesn't touch the next-link of the removed cons cell.
*/
oldquals = lremove(oldrinfo, oldquals);
}
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.257 2002/12/13 19:45:56 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.258 2002/12/17 01:18:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* Prepare columns for assignment to target table.
*/
attnos = attrnos;
- foreach(tl, qry->targetList)
+ /* cannot use foreach here because of possible lremove */
+ tl = qry->targetList;
+ while (tl)
{
TargetEntry *tle = (TargetEntry *) lfirst(tl);
ResTarget *col;
+ /* must advance tl before lremove possibly pfree's it */
+ tl = lnext(tl);
+
if (icolumns == NIL || attnos == NIL)
elog(ERROR, "INSERT has more expressions than target columns");
+
col = (ResTarget *) lfirst(icolumns);
+ Assert(IsA(col, ResTarget));
/*
* When the value is to be set to the column default we can simply
- * drop it now and handle it later on using methods for missing
+ * drop the TLE now and handle it later on using methods for missing
* columns.
*/
- if (!IsA(tle, InsertDefault))
+ if (IsA(tle, InsertDefault))
{
- Assert(IsA(col, ResTarget));
- Assert(!tle->resdom->resjunk);
- updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
- col->indirection);
+ qry->targetList = lremove(tle, qry->targetList);
+ /* Note: the stmt->cols list is not adjusted to match */
}
else
{
- icolumns = lremove(icolumns, icolumns);
- attnos = lremove(attnos, attnos);
- qry->targetList = lremove(tle, qry->targetList);
+ /* Normal case */
+ Assert(!tle->resdom->resjunk);
+ updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
+ col->indirection);
}
icolumns = lnext(icolumns);
}
/*
- * Ensure that the targetlist has the same number of entries that
- * were present in the columns list. Don't do the check for select
+ * Ensure that the targetlist has the same number of entries that
+ * were present in the columns list. Don't do the check unless
+ * an explicit columns list was given, though.
* statements.
*/
if (stmt->cols != NIL && (icolumns != NIL || attnos != NIL))
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.114 2002/12/12 15:49:40 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.115 2002/12/17 01:18:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
{
RangeTblRef *rtr = lfirst(jjt);
- if (IsA(rtr, RangeTblRef) &&rtr->rtindex == rt_index)
+ if (IsA(rtr, RangeTblRef) &&
+ rtr->rtindex == rt_index)
{
newjointree = lremove(rtr, newjointree);
+ /* foreach is safe because we exit loop after lremove... */
break;
}
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.123 2002/12/12 15:49:40 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.124 2002/12/17 01:18:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
if (HeapTupleIsValid(statsTuple))
ReleaseSysCache(statsTuple);
- foreach(l2, varinfos)
+ /* cannot use foreach here because of possible lremove */
+ l2 = varinfos;
+ while (l2)
{
MyVarInfo *varinfo = (MyVarInfo *) lfirst(l2);
+ /* must advance l2 before lremove possibly pfree's it */
+ l2 = lnext(l2);
+
if (var->varno != varinfo->var->varno &&
vars_known_equal(root, var, varinfo->var))
{
}
else
{
- /*
- * Delete the older item. We assume lremove() will not
- * break the lnext link of the item...
- */
+ /* Delete the older item */
varinfos = lremove(varinfo, varinfos);
}
}