diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c
index 664c884a71219f59a861d265da324dc7a6e2ae67..eb05c994b465784e43a478f9cf7dcce5c927cd76 100644
--- a/src/backend/access/common/printtup.c
+++ b/src/backend/access/common/printtup.c
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.80 2004/01/07 18:56:23 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.81 2004/05/26 04:41:03 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -138,7 +138,7 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
 		List	   *targetlist;
 
 		if (portal->strategy == PORTAL_ONE_SELECT)
-			targetlist = ((Query *) lfirst(portal->parseTrees))->targetList;
+			targetlist = ((Query *) linitial(portal->parseTrees))->targetList;
 		else
 			targetlist = NIL;
 
@@ -176,6 +176,7 @@ SendRowDescriptionMessage(TupleDesc typeinfo, List *targetlist, int16 *formats)
 	int			proto = PG_PROTOCOL_MAJOR(FrontendProtocol);
 	int			i;
 	StringInfoData buf;
+	ListCell   *tlist_item = list_head(targetlist);
 
 	pq_beginmessage(&buf, 'T'); /* tuple descriptor message type */
 	pq_sendint(&buf, natts, 2); /* # of attrs in tuples */
@@ -191,16 +192,16 @@ SendRowDescriptionMessage(TupleDesc typeinfo, List *targetlist, int16 *formats)
 		if (proto >= 3)
 		{
 			/* Do we have a non-resjunk tlist item? */
-			while (targetlist &&
-				   ((TargetEntry *) lfirst(targetlist))->resdom->resjunk)
-				targetlist = lnext(targetlist);
-			if (targetlist)
+			while (tlist_item &&
+				   ((TargetEntry *) lfirst(tlist_item))->resdom->resjunk)
+				tlist_item = lnext(tlist_item);
+			if (tlist_item)
 			{
-				Resdom	   *res = ((TargetEntry *) lfirst(targetlist))->resdom;
+				Resdom	   *res = ((TargetEntry *) lfirst(tlist_item))->resdom;
 
 				pq_sendint(&buf, res->resorigtbl, 4);
 				pq_sendint(&buf, res->resorigcol, 2);
-				targetlist = lnext(targetlist);
+				tlist_item = lnext(tlist_item);
 			}
 			else
 			{
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index 1a016d86f80302631e542faea5c11449ba7df802..4a3c2721c7b6595c82308dba37437870c5dec001 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.102 2004/04/01 21:28:43 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.103 2004/05/26 04:41:03 neilc Exp $
  *
  * NOTES
  *	  some of the executor utility code such as "ExecTypeFromTL" should be
@@ -472,7 +472,7 @@ BuildDescForRelation(List *schema)
 {
 	int			natts;
 	AttrNumber	attnum;
-	List	   *p;
+	ListCell   *l;
 	TupleDesc	desc;
 	AttrDefault *attrdef = NULL;
 	TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
@@ -490,9 +490,9 @@ BuildDescForRelation(List *schema)
 
 	attnum = 0;
 
-	foreach(p, schema)
+	foreach(l, schema)
 	{
-		ColumnDef  *entry = lfirst(p);
+		ColumnDef  *entry = lfirst(l);
 
 		/*
 		 * for each entry in the list, get the name and type information
@@ -661,7 +661,7 @@ TypeGetTupleDesc(Oid typeoid, List *colaliases)
 					 errmsg("number of aliases does not match number of columns")));
 
 		/* OK, get the column alias */
-		attname = strVal(lfirst(colaliases));
+		attname = strVal(linitial(colaliases));
 
 		tupdesc = CreateTemplateTupleDesc(1, false);
 		TupleDescInitEntry(tupdesc,
diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c
index 02dbd33341d643d90f59afbb6430180eb3d0ce72..693279f12ac99064326297e587f24e80253aa702 100644
--- a/src/backend/access/nbtree/nbtxlog.c
+++ b/src/backend/access/nbtree/nbtxlog.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.10 2004/01/07 18:56:24 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.11 2004/05/26 04:41:05 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -59,7 +59,7 @@ forget_matching_split(Relation reln, RelFileNode node,
 	Page		page;
 	BTItem		btitem;
 	BlockNumber rightblk;
-	List	   *l;
+	ListCell   *l;
 
 	/* Get downlink TID from page */
 	buffer = XLogReadBuffer(false, reln, insertblk);
@@ -964,7 +964,7 @@ btree_xlog_startup(void)
 void
 btree_xlog_cleanup(void)
 {
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, incomplete_splits)
 	{
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index debf24e892d5738c2810e59071f75456540fbf47..4047958b1d978851c800e4c4bf304dbfa37f59f6 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.67 2004/05/21 05:07:56 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.68 2004/05/26 04:41:05 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -271,7 +271,7 @@ Boot_BuildIndsStmt:
 
 boot_index_params:
 		boot_index_params COMMA boot_index_param	{ $$ = lappend($1, $3); }
-		| boot_index_param							{ $$ = makeList1($1); }
+		| boot_index_param							{ $$ = list_make1($1); }
 		;
 
 boot_index_param:
@@ -280,7 +280,7 @@ boot_index_param:
 					IndexElem *n = makeNode(IndexElem);
 					n->name = LexIDStr($1);
 					n->expr = NULL;
-					n->opclass = makeList1(makeString(LexIDStr($2)));
+					n->opclass = list_make1(makeString(LexIDStr($2)));
 					$$ = n;
 				}
 		;
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 8e27f10d39a8226f70b57ae67b6eccf77ec42f49..cabeb690884ae9882899e76944dd6db7f5cc8e87 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.98 2004/05/11 17:36:12 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.99 2004/05/26 04:41:06 neilc Exp $
  *
  * NOTES
  *	  See acl.h.
@@ -110,7 +110,7 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
 					 AclId grantor_uid, AclId owner_uid)
 {
 	unsigned	modechg;
-	List	   *j;
+	ListCell   *j;
 	Acl		   *new_acl;
 
 	modechg = is_grant ? ACL_MODECHG_ADD : ACL_MODECHG_DEL;
@@ -221,16 +221,16 @@ static void
 ExecuteGrantStmt_Relation(GrantStmt *stmt)
 {
 	AclMode		privileges;
-	List	   *i;
+	ListCell   *i;
 
-	if (lfirsti(stmt->privileges) == ACL_ALL_RIGHTS)
+	if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
 		privileges = ACL_ALL_RIGHTS_RELATION;
 	else
 	{
 		privileges = ACL_NO_RIGHTS;
 		foreach(i, stmt->privileges)
 		{
-			AclMode		priv = lfirsti(i);
+			AclMode		priv = lfirst_int(i);
 
 			if (priv & ~((AclMode) ACL_ALL_RIGHTS_RELATION))
 				ereport(ERROR,
@@ -328,16 +328,16 @@ static void
 ExecuteGrantStmt_Database(GrantStmt *stmt)
 {
 	AclMode		privileges;
-	List	   *i;
+	ListCell   *i;
 
-	if (lfirsti(stmt->privileges) == ACL_ALL_RIGHTS)
+	if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
 		privileges = ACL_ALL_RIGHTS_DATABASE;
 	else
 	{
 		privileges = ACL_NO_RIGHTS;
 		foreach(i, stmt->privileges)
 		{
-			AclMode		priv = lfirsti(i);
+			AclMode		priv = lfirst_int(i);
 
 			if (priv & ~((AclMode) ACL_ALL_RIGHTS_DATABASE))
 				ereport(ERROR,
@@ -433,16 +433,16 @@ static void
 ExecuteGrantStmt_Function(GrantStmt *stmt)
 {
 	AclMode		privileges;
-	List	   *i;
+	ListCell   *i;
 
-	if (lfirsti(stmt->privileges) == ACL_ALL_RIGHTS)
+	if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
 		privileges = ACL_ALL_RIGHTS_FUNCTION;
 	else
 	{
 		privileges = ACL_NO_RIGHTS;
 		foreach(i, stmt->privileges)
 		{
-			AclMode		priv = lfirsti(i);
+			AclMode		priv = lfirst_int(i);
 
 			if (priv & ~((AclMode) ACL_ALL_RIGHTS_FUNCTION))
 				ereport(ERROR,
@@ -534,16 +534,16 @@ static void
 ExecuteGrantStmt_Language(GrantStmt *stmt)
 {
 	AclMode		privileges;
-	List	   *i;
+	ListCell   *i;
 
-	if (lfirsti(stmt->privileges) == ACL_ALL_RIGHTS)
+	if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
 		privileges = ACL_ALL_RIGHTS_LANGUAGE;
 	else
 	{
 		privileges = ACL_NO_RIGHTS;
 		foreach(i, stmt->privileges)
 		{
-			AclMode		priv = lfirsti(i);
+			AclMode		priv = lfirst_int(i);
 
 			if (priv & ~((AclMode) ACL_ALL_RIGHTS_LANGUAGE))
 				ereport(ERROR,
@@ -643,16 +643,16 @@ static void
 ExecuteGrantStmt_Namespace(GrantStmt *stmt)
 {
 	AclMode		privileges;
-	List	   *i;
+	ListCell   *i;
 
-	if (lfirsti(stmt->privileges) == ACL_ALL_RIGHTS)
+	if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
 		privileges = ACL_ALL_RIGHTS_NAMESPACE;
 	else
 	{
 		privileges = ACL_NO_RIGHTS;
 		foreach(i, stmt->privileges)
 		{
-			AclMode		priv = lfirsti(i);
+			AclMode		priv = lfirst_int(i);
 
 			if (priv & ~((AclMode) ACL_ALL_RIGHTS_NAMESPACE))
 				ereport(ERROR,
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 5f2b2ea28a070b816449d3858861d820a9004de4..9d4e1c6a5c48773571b2d948d3769dbccee4ada0 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.35 2004/05/05 04:48:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.36 2004/05/26 04:41:06 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -841,7 +841,7 @@ recordDependencyOnExpr(const ObjectAddress *depender,
 	init_object_addresses(&context.addrs);
 
 	/* Set up interpretation for Vars at varlevelsup = 0 */
-	context.rtables = makeList1(rtable);
+	context.rtables = list_make1(rtable);
 
 	/* Scan the expression tree for referenceable objects */
 	find_expr_references_walker(expr, &context);
@@ -883,7 +883,7 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
 	rte.rtekind = RTE_RELATION;
 	rte.relid = relId;
 
-	context.rtables = makeList1(makeList1(&rte));
+	context.rtables = list_make1(list_make1(&rte));
 
 	/* Scan the expression tree for referenceable objects */
 	find_expr_references_walker(expr, &context);
@@ -960,24 +960,14 @@ find_expr_references_walker(Node *node,
 	if (IsA(node, Var))
 	{
 		Var		   *var = (Var *) node;
-		int			levelsup;
-		List	   *rtable,
-				   *rtables;
+		List	   *rtable;
 		RangeTblEntry *rte;
 
 		/* Find matching rtable entry, or complain if not found */
-		levelsup = var->varlevelsup;
-		rtables = context->rtables;
-		while (levelsup--)
-		{
-			if (rtables == NIL)
-				break;
-			rtables = lnext(rtables);
-		}
-		if (rtables == NIL)
+		if (var->varlevelsup >= list_length(context->rtables))
 			elog(ERROR, "invalid varlevelsup %d", var->varlevelsup);
-		rtable = lfirst(rtables);
-		if (var->varno <= 0 || var->varno > length(rtable))
+		rtable = (List *) list_nth(context->rtables, var->varlevelsup);
+		if (var->varno <= 0 || var->varno > list_length(rtable))
 			elog(ERROR, "invalid varno %d", var->varno);
 		rte = rt_fetch(var->varno, rtable);
 		if (rte->rtekind == RTE_RELATION)
@@ -994,13 +984,15 @@ find_expr_references_walker(Node *node,
 
 			/* We must make the context appropriate for join's level */
 			save_rtables = context->rtables;
-			context->rtables = rtables;
+			context->rtables = list_copy_tail(context->rtables,
+											  var->varlevelsup);
 			if (var->varattno <= 0 ||
-				var->varattno > length(rte->joinaliasvars))
+				var->varattno > list_length(rte->joinaliasvars))
 				elog(ERROR, "invalid varattno %d", var->varattno);
-			find_expr_references_walker((Node *) nth(var->varattno - 1,
-													 rte->joinaliasvars),
+			find_expr_references_walker((Node *) list_nth(rte->joinaliasvars,
+														  var->varattno - 1),
 										context);
+			list_free(context->rtables);
 			context->rtables = save_rtables;
 		}
 		return false;
@@ -1056,11 +1048,11 @@ find_expr_references_walker(Node *node,
 	if (IsA(node, SubLink))
 	{
 		SubLink    *sublink = (SubLink *) node;
-		List	   *opid;
+		ListCell   *opid;
 
 		foreach(opid, sublink->operOids)
 		{
-			add_object_address(OCLASS_OPERATOR, lfirsto(opid), 0,
+			add_object_address(OCLASS_OPERATOR, lfirst_oid(opid), 0,
 							   &context->addrs);
 		}
 		/* fall through to examine arguments */
@@ -1074,7 +1066,7 @@ find_expr_references_walker(Node *node,
 	{
 		/* Recurse into RTE subquery or not-yet-planned sublink subquery */
 		Query	   *query = (Query *) node;
-		List	   *rtable;
+		ListCell   *rtable;
 		bool		result;
 
 		/*
@@ -1099,7 +1091,7 @@ find_expr_references_walker(Node *node,
 								   find_expr_references_walker,
 								   (void *) context,
 								   QTW_IGNORE_JOINALIASES);
-		context->rtables = lnext(context->rtables);
+		context->rtables = list_delete_first(context->rtables);
 		return result;
 	}
 	return expression_tree_walker(node, find_expr_references_walker,
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 94f1fd2a13d2570c1fb5787947e9162f0a254046..a7ffe38b53155f1611f7a4104d7c843ecd785c47 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.264 2004/05/08 19:09:24 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.265 2004/05/26 04:41:07 neilc Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1379,11 +1379,11 @@ StoreRelCheck(Relation rel, char *ccname, char *ccbin)
 	 * contents of subselects.
 	 */
 	varList = pull_var_clause(expr, false);
-	keycount = length(varList);
+	keycount = list_length(varList);
 
 	if (keycount > 0)
 	{
-		List	   *vl;
+		ListCell   *vl;
 		int			i = 0;
 
 		attNos = (int16 *) palloc(keycount * sizeof(int16));
@@ -1505,7 +1505,7 @@ AddRelationRawConstraints(Relation rel,
 	RangeTblEntry *rte;
 	int			numchecks;
 	int			constr_name_ctr = 0;
-	List	   *listptr;
+	ListCell   *cell;
 	Node	   *expr;
 	CookedConstraint *cooked;
 
@@ -1540,9 +1540,9 @@ AddRelationRawConstraints(Relation rel,
 	/*
 	 * Process column default expressions.
 	 */
-	foreach(listptr, rawColDefaults)
+	foreach(cell, rawColDefaults)
 	{
-		RawColumnDefault *colDef = (RawColumnDefault *) lfirst(listptr);
+		RawColumnDefault *colDef = (RawColumnDefault *) lfirst(cell);
 		Form_pg_attribute atp = rel->rd_att->attrs[colDef->attnum - 1];
 
 		expr = cookDefault(pstate, colDef->raw_default,
@@ -1563,9 +1563,9 @@ AddRelationRawConstraints(Relation rel,
 	 * Process constraint expressions.
 	 */
 	numchecks = numoldchecks;
-	foreach(listptr, rawConstraints)
+	foreach(cell, rawConstraints)
 	{
-		Constraint *cdef = (Constraint *) lfirst(listptr);
+		Constraint *cdef = (Constraint *) lfirst(cell);
 		char	   *ccname;
 
 		if (cdef->contype != CONSTR_CHECK || cdef->raw_expr == NULL)
@@ -1575,7 +1575,7 @@ AddRelationRawConstraints(Relation rel,
 		/* Check name uniqueness, or generate a new name */
 		if (cdef->name != NULL)
 		{
-			List	   *listptr2;
+			ListCell   *cell2;
 
 			ccname = cdef->name;
 			/* Check against pre-existing constraints */
@@ -1589,9 +1589,9 @@ AddRelationRawConstraints(Relation rel,
 								ccname, RelationGetRelationName(rel))));
 			/* Check against other new constraints */
 			/* Needed because we don't do CommandCounterIncrement in loop */
-			foreach(listptr2, rawConstraints)
+			foreach(cell2, rawConstraints)
 			{
-				Constraint *cdef2 = (Constraint *) lfirst(listptr2);
+				Constraint *cdef2 = (Constraint *) lfirst(cell2);
 
 				if (cdef2 == cdef ||
 					cdef2->contype != CONSTR_CHECK ||
@@ -1611,7 +1611,7 @@ AddRelationRawConstraints(Relation rel,
 
 			do
 			{
-				List	   *listptr2;
+				ListCell   *cell2;
 
 				/*
 				 * Generate a name that does not conflict with
@@ -1629,9 +1629,9 @@ AddRelationRawConstraints(Relation rel,
 				 * name.
 				 */
 				success = true;
-				foreach(listptr2, rawConstraints)
+				foreach(cell2, rawConstraints)
 				{
-					Constraint *cdef2 = (Constraint *) lfirst(listptr2);
+					Constraint *cdef2 = (Constraint *) lfirst(cell2);
 
 					if (cdef2 == cdef ||
 						cdef2->contype != CONSTR_CHECK ||
@@ -1660,7 +1660,7 @@ AddRelationRawConstraints(Relation rel,
 		/*
 		 * Make sure no outside relations are referred to.
 		 */
-		if (length(pstate->p_rtable) != 1)
+		if (list_length(pstate->p_rtable) != 1)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
 					 errmsg("only table \"%s\" can be referenced in check constraint",
@@ -1949,7 +1949,7 @@ static void
 RelationTruncateIndexes(Oid heapId)
 {
 	Relation	heapRelation;
-	List	   *indlist;
+	ListCell   *indlist;
 
 	/*
 	 * Open the heap rel.  We need grab no lock because we assume
@@ -1960,7 +1960,7 @@ RelationTruncateIndexes(Oid heapId)
 	/* Ask the relcache to produce a list of the indexes of the rel */
 	foreach(indlist, RelationGetIndexList(heapRelation))
 	{
-		Oid			indexId = lfirsto(indlist);
+		Oid			indexId = lfirst_oid(indlist);
 		Relation	currentIndex;
 		IndexInfo  *indexInfo;
 
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index d6d38795df8049bc8e481e556304a28860a92883..0ccecac66808f7986c7886255bc7c6c7aae1daab 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.231 2004/05/08 19:09:24 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.232 2004/05/26 04:41:07 neilc Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -88,7 +88,7 @@ ConstructTupleDescriptor(Relation heapRelation,
 						 Oid *classObjectId)
 {
 	int			numatts = indexInfo->ii_NumIndexAttrs;
-	List	   *indexprs = indexInfo->ii_Expressions;
+	ListCell   *indexpr_item = list_head(indexInfo->ii_Expressions);
 	TupleDesc	heapTupDesc;
 	TupleDesc	indexTupDesc;
 	int			natts;			/* #atts in heap rel --- for error checks */
@@ -165,10 +165,10 @@ ConstructTupleDescriptor(Relation heapRelation,
 			/* Expressional index */
 			Node	   *indexkey;
 
-			if (indexprs == NIL)	/* shouldn't happen */
+			if (indexpr_item == NULL)	/* shouldn't happen */
 				elog(ERROR, "too few entries in indexprs list");
-			indexkey = (Node *) lfirst(indexprs);
-			indexprs = lnext(indexprs);
+			indexkey = (Node *) lfirst(indexpr_item);
+			indexpr_item = lnext(indexpr_item);
 
 			/*
 			 * Make the attribute's name "pg_expresssion_nnn" (maybe think
@@ -928,7 +928,7 @@ FormIndexDatum(IndexInfo *indexInfo,
 			   Datum *datum,
 			   char *nullv)
 {
-	List	   *indexprs;
+	ListCell   *indexpr_item;
 	int			i;
 
 	if (indexInfo->ii_Expressions != NIL &&
@@ -941,7 +941,7 @@ FormIndexDatum(IndexInfo *indexInfo,
 		/* Check caller has set up context correctly */
 		Assert(GetPerTupleExprContext(estate)->ecxt_scantuple->val == heapTuple);
 	}
-	indexprs = indexInfo->ii_ExpressionsState;
+	indexpr_item = list_head(indexInfo->ii_ExpressionsState);
 
 	for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
 	{
@@ -962,19 +962,19 @@ FormIndexDatum(IndexInfo *indexInfo,
 			/*
 			 * Index expression --- need to evaluate it.
 			 */
-			if (indexprs == NIL)
+			if (indexpr_item == NULL)
 				elog(ERROR, "wrong number of index expressions");
-			iDatum = ExecEvalExprSwitchContext((ExprState *) lfirst(indexprs),
+			iDatum = ExecEvalExprSwitchContext((ExprState *) lfirst(indexpr_item),
 										  GetPerTupleExprContext(estate),
 											   &isNull,
 											   NULL);
-			indexprs = lnext(indexprs);
+			indexpr_item = lnext(indexpr_item);
 		}
 		datum[i] = iDatum;
 		nullv[i] = (isNull) ? 'n' : ' ';
 	}
 
-	if (indexprs != NIL)
+	if (indexpr_item != NULL)
 		elog(ERROR, "wrong number of index expressions");
 }
 
@@ -1738,8 +1738,8 @@ reindex_relation(Oid relid, bool toast_too)
 	bool		is_pg_class;
 	bool		result;
 	List	   *indexIds,
-			   *doneIndexes,
-			   *indexId;
+			   *doneIndexes;
+	ListCell   *indexId;
 
 	/*
 	 * Ensure to hold an exclusive lock throughout the transaction. The
@@ -1780,7 +1780,7 @@ reindex_relation(Oid relid, bool toast_too)
 	/* Reindex all the indexes. */
 	foreach(indexId, indexIds)
 	{
-		Oid		indexOid = lfirsto(indexId);
+		Oid		indexOid = lfirst_oid(indexId);
 
 		if (is_pg_class)
 			RelationSetIndexList(rel, doneIndexes);
@@ -1790,7 +1790,7 @@ reindex_relation(Oid relid, bool toast_too)
 		CommandCounterIncrement();
 
 		if (is_pg_class)
-			doneIndexes = lappendo(doneIndexes, indexOid);
+			doneIndexes = lappend_oid(doneIndexes, indexOid);
 	}
 
 	if (is_pg_class)
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 91a604eac7eaa65398c8c9c590cdf60c34c4961b..e9b5a35ba72a368496762474fc1cd16badb95aa3 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.63 2004/02/13 01:08:20 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.64 2004/05/26 04:41:07 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -276,13 +276,13 @@ Oid
 RelnameGetRelid(const char *relname)
 {
 	Oid			relid;
-	List	   *lptr;
+	ListCell   *l;
 
 	recomputeNamespacePath();
 
-	foreach(lptr, namespaceSearchPath)
+	foreach(l, namespaceSearchPath)
 	{
-		Oid			namespaceId = lfirsto(lptr);
+		Oid			namespaceId = lfirst_oid(l);
 
 		relid = get_relname_relid(relname, namespaceId);
 		if (OidIsValid(relid))
@@ -320,11 +320,11 @@ RelationIsVisible(Oid relid)
 	/*
 	 * Quick check: if it ain't in the path at all, it ain't visible.
 	 * Items in the system namespace are surely in the path and so we
-	 * needn't even do oidMember() for them.
+	 * needn't even do list_member_oid() for them.
 	 */
 	relnamespace = relform->relnamespace;
 	if (relnamespace != PG_CATALOG_NAMESPACE &&
-		!oidMember(relnamespace, namespaceSearchPath))
+		!list_member_oid(namespaceSearchPath, relnamespace))
 		visible = false;
 	else
 	{
@@ -356,13 +356,13 @@ Oid
 TypenameGetTypid(const char *typname)
 {
 	Oid			typid;
-	List	   *lptr;
+	ListCell   *l;
 
 	recomputeNamespacePath();
 
-	foreach(lptr, namespaceSearchPath)
+	foreach(l, namespaceSearchPath)
 	{
-		Oid			namespaceId = lfirsto(lptr);
+		Oid			namespaceId = lfirst_oid(l);
 
 		typid = GetSysCacheOid(TYPENAMENSP,
 							   PointerGetDatum(typname),
@@ -402,11 +402,11 @@ TypeIsVisible(Oid typid)
 	/*
 	 * Quick check: if it ain't in the path at all, it ain't visible.
 	 * Items in the system namespace are surely in the path and so we
-	 * needn't even do oidMember() for them.
+	 * needn't even do list_member_oid() for them.
 	 */
 	typnamespace = typform->typnamespace;
 	if (typnamespace != PG_CATALOG_NAMESPACE &&
-		!oidMember(typnamespace, namespaceSearchPath))
+		!list_member_oid(namespaceSearchPath, typnamespace))
 		visible = false;
 	else
 	{
@@ -496,15 +496,15 @@ FuncnameGetCandidates(List *names, int nargs)
 		else
 		{
 			/* Consider only procs that are in the search path */
-			List	   *nsp;
+			ListCell   *nsp;
 
 			foreach(nsp, namespaceSearchPath)
 			{
-				if (procform->pronamespace == lfirsto(nsp))
+				if (procform->pronamespace == lfirst_oid(nsp))
 					break;
 				pathpos++;
 			}
-			if (nsp == NIL)
+			if (nsp == NULL)
 				continue;		/* proc is not in search path */
 
 			/*
@@ -603,11 +603,11 @@ FunctionIsVisible(Oid funcid)
 	/*
 	 * Quick check: if it ain't in the path at all, it ain't visible.
 	 * Items in the system namespace are surely in the path and so we
-	 * needn't even do oidMember() for them.
+	 * needn't even do list_member_oid() for them.
 	 */
 	pronamespace = procform->pronamespace;
 	if (pronamespace != PG_CATALOG_NAMESPACE &&
-		!oidMember(pronamespace, namespaceSearchPath))
+		!list_member_oid(namespaceSearchPath, pronamespace))
 		visible = false;
 	else
 	{
@@ -623,7 +623,7 @@ FunctionIsVisible(Oid funcid)
 
 		visible = false;
 
-		clist = FuncnameGetCandidates(makeList1(makeString(proname)), nargs);
+		clist = FuncnameGetCandidates(list_make1(makeString(proname)), nargs);
 
 		for (; clist; clist = clist->next)
 		{
@@ -727,15 +727,15 @@ OpernameGetCandidates(List *names, char oprkind)
 		else
 		{
 			/* Consider only opers that are in the search path */
-			List	   *nsp;
+			ListCell   *nsp;
 
 			foreach(nsp, namespaceSearchPath)
 			{
-				if (operform->oprnamespace == lfirsto(nsp))
+				if (operform->oprnamespace == lfirst_oid(nsp))
 					break;
 				pathpos++;
 			}
-			if (nsp == NIL)
+			if (nsp == NULL)
 				continue;		/* oper is not in search path */
 
 			/*
@@ -832,11 +832,11 @@ OperatorIsVisible(Oid oprid)
 	/*
 	 * Quick check: if it ain't in the path at all, it ain't visible.
 	 * Items in the system namespace are surely in the path and so we
-	 * needn't even do oidMember() for them.
+	 * needn't even do list_member_oid() for them.
 	 */
 	oprnamespace = oprform->oprnamespace;
 	if (oprnamespace != PG_CATALOG_NAMESPACE &&
-		!oidMember(oprnamespace, namespaceSearchPath))
+		!list_member_oid(namespaceSearchPath, oprnamespace))
 		visible = false;
 	else
 	{
@@ -852,7 +852,7 @@ OperatorIsVisible(Oid oprid)
 
 		visible = false;
 
-		clist = OpernameGetCandidates(makeList1(makeString(oprname)),
+		clist = OpernameGetCandidates(list_make1(makeString(oprname)),
 									  oprform->oprkind);
 
 		for (; clist; clist = clist->next)
@@ -903,16 +903,16 @@ OpclassGetCandidates(Oid amid)
 		Form_pg_opclass opcform = (Form_pg_opclass) GETSTRUCT(opctup);
 		int			pathpos = 0;
 		OpclassCandidateList newResult;
-		List	   *nsp;
+		ListCell   *nsp;
 
 		/* Consider only opclasses that are in the search path */
 		foreach(nsp, namespaceSearchPath)
 		{
-			if (opcform->opcnamespace == lfirsto(nsp))
+			if (opcform->opcnamespace == lfirst_oid(nsp))
 				break;
 			pathpos++;
 		}
-		if (nsp == NIL)
+		if (nsp == NULL)
 			continue;			/* opclass is not in search path */
 
 		/*
@@ -998,13 +998,13 @@ Oid
 OpclassnameGetOpcid(Oid amid, const char *opcname)
 {
 	Oid			opcid;
-	List	   *lptr;
+	ListCell   *l;
 
 	recomputeNamespacePath();
 
-	foreach(lptr, namespaceSearchPath)
+	foreach(l, namespaceSearchPath)
 	{
-		Oid			namespaceId = lfirsto(lptr);
+		Oid			namespaceId = lfirst_oid(l);
 
 		opcid = GetSysCacheOid(CLAAMNAMENSP,
 							   ObjectIdGetDatum(amid),
@@ -1045,11 +1045,11 @@ OpclassIsVisible(Oid opcid)
 	/*
 	 * Quick check: if it ain't in the path at all, it ain't visible.
 	 * Items in the system namespace are surely in the path and so we
-	 * needn't even do oidMember() for them.
+	 * needn't even do list_member_oid() for them.
 	 */
 	opcnamespace = opcform->opcnamespace;
 	if (opcnamespace != PG_CATALOG_NAMESPACE &&
-		!oidMember(opcnamespace, namespaceSearchPath))
+		!list_member_oid(namespaceSearchPath, opcnamespace))
 		visible = false;
 	else
 	{
@@ -1080,13 +1080,13 @@ Oid
 ConversionGetConid(const char *conname)
 {
 	Oid			conid;
-	List	   *lptr;
+	ListCell   *l;
 
 	recomputeNamespacePath();
 
-	foreach(lptr, namespaceSearchPath)
+	foreach(l, namespaceSearchPath)
 	{
-		Oid			namespaceId = lfirsto(lptr);
+		Oid			namespaceId = lfirst_oid(l);
 
 		conid = GetSysCacheOid(CONNAMENSP,
 							   PointerGetDatum(conname),
@@ -1126,11 +1126,11 @@ ConversionIsVisible(Oid conid)
 	/*
 	 * Quick check: if it ain't in the path at all, it ain't visible.
 	 * Items in the system namespace are surely in the path and so we
-	 * needn't even do oidMember() for them.
+	 * needn't even do list_member_oid() for them.
 	 */
 	connamespace = conform->connamespace;
 	if (connamespace != PG_CATALOG_NAMESPACE &&
-		!oidMember(connamespace, namespaceSearchPath))
+		!list_member_oid(namespaceSearchPath, connamespace))
 		visible = false;
 	else
 	{
@@ -1166,17 +1166,17 @@ DeconstructQualifiedName(List *names,
 	char	   *schemaname = NULL;
 	char	   *objname = NULL;
 
-	switch (length(names))
+	switch (list_length(names))
 	{
 		case 1:
-			objname = strVal(lfirst(names));
+			objname = strVal(linitial(names));
 			break;
 		case 2:
-			schemaname = strVal(lfirst(names));
+			schemaname = strVal(linitial(names));
 			objname = strVal(lsecond(names));
 			break;
 		case 3:
-			catalogname = strVal(lfirst(names));
+			catalogname = strVal(linitial(names));
 			schemaname = strVal(lsecond(names));
 			objname = strVal(lthird(names));
 
@@ -1287,17 +1287,17 @@ makeRangeVarFromNameList(List *names)
 {
 	RangeVar   *rel = makeRangeVar(NULL, NULL);
 
-	switch (length(names))
+	switch (list_length(names))
 	{
 		case 1:
-			rel->relname = strVal(lfirst(names));
+			rel->relname = strVal(linitial(names));
 			break;
 		case 2:
-			rel->schemaname = strVal(lfirst(names));
+			rel->schemaname = strVal(linitial(names));
 			rel->relname = strVal(lsecond(names));
 			break;
 		case 3:
-			rel->catalogname = strVal(lfirst(names));
+			rel->catalogname = strVal(linitial(names));
 			rel->schemaname = strVal(lsecond(names));
 			rel->relname = strVal(lthird(names));
 			break;
@@ -1323,13 +1323,13 @@ char *
 NameListToString(List *names)
 {
 	StringInfoData string;
-	List	   *l;
+	ListCell   *l;
 
 	initStringInfo(&string);
 
 	foreach(l, names)
 	{
-		if (l != names)
+		if (l != list_head(names))
 			appendStringInfoChar(&string, '.');
 		appendStringInfoString(&string, strVal(lfirst(l)));
 	}
@@ -1348,13 +1348,13 @@ char *
 NameListToQuotedString(List *names)
 {
 	StringInfoData string;
-	List	   *l;
+	ListCell   *l;
 
 	initStringInfo(&string);
 
 	foreach(l, names)
 	{
-		if (l != names)
+		if (l != list_head(names))
 			appendStringInfoChar(&string, '.');
 		appendStringInfoString(&string, quote_identifier(strVal(lfirst(l))));
 	}
@@ -1435,7 +1435,7 @@ FindConversionByName(List *name)
 	char	   *conversion_name;
 	Oid			namespaceId;
 	Oid			conoid;
-	List	   *lptr;
+	ListCell   *l;
 
 	/* deconstruct the name list */
 	DeconstructQualifiedName(name, &schemaname, &conversion_name);
@@ -1451,9 +1451,9 @@ FindConversionByName(List *name)
 		/* search for it in search path */
 		recomputeNamespacePath();
 
-		foreach(lptr, namespaceSearchPath)
+		foreach(l, namespaceSearchPath)
 		{
-			namespaceId = lfirsto(lptr);
+			namespaceId = lfirst_oid(l);
 			conoid = FindConversion(conversion_name, namespaceId);
 			if (OidIsValid(conoid))
 				return conoid;
@@ -1471,13 +1471,13 @@ Oid
 FindDefaultConversionProc(int4 for_encoding, int4 to_encoding)
 {
 	Oid			proc;
-	List	   *lptr;
+	ListCell   *l;
 
 	recomputeNamespacePath();
 
-	foreach(lptr, namespaceSearchPath)
+	foreach(l, namespaceSearchPath)
 	{
-		Oid			namespaceId = lfirsto(lptr);
+		Oid			namespaceId = lfirst_oid(l);
 
 		proc = FindDefaultConversion(namespaceId, for_encoding, to_encoding);
 		if (OidIsValid(proc))
@@ -1499,7 +1499,7 @@ recomputeNamespacePath(void)
 	List	   *namelist;
 	List	   *oidlist;
 	List	   *newpath;
-	List	   *l;
+	ListCell   *l;
 	Oid			firstNS;
 	MemoryContext oldcxt;
 
@@ -1550,10 +1550,10 @@ recomputeNamespacePath(void)
 											 0, 0, 0);
 				ReleaseSysCache(tuple);
 				if (OidIsValid(namespaceId) &&
-					!oidMember(namespaceId, oidlist) &&
+					!list_member_oid(oidlist, namespaceId) &&
 					pg_namespace_aclcheck(namespaceId, userId,
 										  ACL_USAGE) == ACLCHECK_OK)
-					oidlist = lappendo(oidlist, namespaceId);
+					oidlist = lappend_oid(oidlist, namespaceId);
 			}
 		}
 		else
@@ -1563,10 +1563,10 @@ recomputeNamespacePath(void)
 										 CStringGetDatum(curname),
 										 0, 0, 0);
 			if (OidIsValid(namespaceId) &&
-				!oidMember(namespaceId, oidlist) &&
+				!list_member_oid(oidlist, namespaceId) &&
 				pg_namespace_aclcheck(namespaceId, userId,
 									  ACL_USAGE) == ACLCHECK_OK)
-				oidlist = lappendo(oidlist, namespaceId);
+				oidlist = lappend_oid(oidlist, namespaceId);
 		}
 	}
 
@@ -1576,34 +1576,34 @@ recomputeNamespacePath(void)
 	if (oidlist == NIL)
 		firstNS = InvalidOid;
 	else
-		firstNS = lfirsto(oidlist);
+		firstNS = linitial_oid(oidlist);
 
 	/*
 	 * Add any implicitly-searched namespaces to the list.	Note these go
 	 * on the front, not the back; also notice that we do not check USAGE
 	 * permissions for these.
 	 */
-	if (!oidMember(PG_CATALOG_NAMESPACE, oidlist))
-		oidlist = lconso(PG_CATALOG_NAMESPACE, oidlist);
+	if (!list_member_oid(oidlist, PG_CATALOG_NAMESPACE))
+		oidlist = lcons_oid(PG_CATALOG_NAMESPACE, oidlist);
 
 	if (OidIsValid(myTempNamespace) &&
-		!oidMember(myTempNamespace, oidlist))
-		oidlist = lconso(myTempNamespace, oidlist);
+		!list_member_oid(oidlist, myTempNamespace))
+		oidlist = lcons_oid(myTempNamespace, oidlist);
 
 	if (OidIsValid(mySpecialNamespace) &&
-		!oidMember(mySpecialNamespace, oidlist))
-		oidlist = lconso(mySpecialNamespace, oidlist);
+		!list_member_oid(oidlist, mySpecialNamespace))
+		oidlist = lcons_oid(mySpecialNamespace, oidlist);
 
 	/*
 	 * Now that we've successfully built the new list of namespace OIDs,
 	 * save it in permanent storage.
 	 */
 	oldcxt = MemoryContextSwitchTo(TopMemoryContext);
-	newpath = listCopy(oidlist);
+	newpath = list_copy(oidlist);
 	MemoryContextSwitchTo(oldcxt);
 
 	/* Now safe to assign to state variable. */
-	freeList(namespaceSearchPath);
+	list_free(namespaceSearchPath);
 	namespaceSearchPath = newpath;
 
 	/*
@@ -1621,8 +1621,8 @@ recomputeNamespacePath(void)
 
 	/* Clean up. */
 	pfree(rawname);
-	freeList(namelist);
-	freeList(oidlist);
+	list_free(namelist);
+	list_free(oidlist);
 }
 
 /*
@@ -1783,7 +1783,7 @@ assign_search_path(const char *newval, bool doit, GucSource source)
 {
 	char	   *rawname;
 	List	   *namelist;
-	List	   *l;
+	ListCell   *l;
 
 	/* Need a modifiable copy of string */
 	rawname = pstrdup(newval);
@@ -1793,7 +1793,7 @@ assign_search_path(const char *newval, bool doit, GucSource source)
 	{
 		/* syntax error in name list */
 		pfree(rawname);
-		freeList(namelist);
+		list_free(namelist);
 		return NULL;
 	}
 
@@ -1831,7 +1831,7 @@ assign_search_path(const char *newval, bool doit, GucSource source)
 	}
 
 	pfree(rawname);
-	freeList(namelist);
+	list_free(namelist);
 
 	/*
 	 * We mark the path as needing recomputation, but don't do anything
@@ -1862,7 +1862,7 @@ InitializeSearchPath(void)
 		MemoryContext oldcxt;
 
 		oldcxt = MemoryContextSwitchTo(TopMemoryContext);
-		namespaceSearchPath = makeListo1(PG_CATALOG_NAMESPACE);
+		namespaceSearchPath = list_make1_oid(PG_CATALOG_NAMESPACE);
 		MemoryContextSwitchTo(oldcxt);
 		defaultCreationNamespace = PG_CATALOG_NAMESPACE;
 		firstExplicitNamespace = PG_CATALOG_NAMESPACE;
@@ -1895,12 +1895,12 @@ NamespaceCallback(Datum arg, Oid relid)
 }
 
 /*
- * Fetch the active search path, expressed as a List of OIDs.
+ * Fetch the active search path. The return value is a palloc'ed list
+ * of OIDs; the caller is responsible for freeing this storage as
+ * appropriate.
  *
  * The returned list includes the implicitly-prepended namespaces only if
  * includeImplicit is true.
- *
- * NB: caller must treat the list as read-only!
  */
 List *
 fetch_search_path(bool includeImplicit)
@@ -1909,11 +1909,11 @@ fetch_search_path(bool includeImplicit)
 
 	recomputeNamespacePath();
 
-	result = namespaceSearchPath;
+	result = list_copy(namespaceSearchPath);
 	if (!includeImplicit)
 	{
-		while (result && lfirsto(result) != firstExplicitNamespace)
-			result = lnext(result);
+		while (result && linitial_oid(result) != firstExplicitNamespace)
+			result = list_delete_first(result);
 	}
 
 	return result;
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 749ad4412783a589c312e0e8476510031b358ba4..3a184182b8201cc8832316868969af10fba0e3b3 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.115 2004/04/02 23:14:05 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.116 2004/05/26 04:41:08 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -374,7 +374,7 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
 	Query	   *parse;
 	int			cmd;
 	List	   *tlist;
-	List	   *tlistitem;
+	ListCell   *tlistitem;
 	int			tlistlen;
 	Oid			typerelid;
 	Oid			restype;
@@ -396,7 +396,7 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
 	}
 
 	/* find the final query */
-	parse = (Query *) llast(queryTreeList);
+	parse = (Query *) lfirst(list_tail(queryTreeList));
 
 	cmd = parse->commandType;
 	tlist = parse->targetList;
@@ -448,7 +448,7 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
 							format_type_be(rettype)),
 			 errdetail("Final SELECT must return exactly one column.")));
 
-		restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
+		restype = ((TargetEntry *) linitial(tlist))->resdom->restype;
 		if (!IsBinaryCoercible(restype, rettype))
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
@@ -471,7 +471,7 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
 		 */
 		if (tlistlen == 1)
 		{
-			restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
+			restype = ((TargetEntry *) linitial(tlist))->resdom->restype;
 			if (IsBinaryCoercible(restype, rettype))
 				return false;	/* NOT returning whole tuple */
 		}
@@ -556,7 +556,7 @@ check_sql_fn_retval(Oid rettype, char fn_typtype, List *queryTreeList)
 		 */
 		if (tlistlen == 1)
 		{
-			restype = ((TargetEntry *) lfirst(tlist))->resdom->restype;
+			restype = ((TargetEntry *) linitial(tlist))->resdom->restype;
 			if (IsBinaryCoercible(restype, rettype))
 				return false;	/* NOT returning whole tuple */
 		}
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index d587245ef97c257e24dc6ea4d38e2526f8b8e596..c8865b3dbde3851708699a5d66edfc638af29707 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.17 2004/05/07 00:24:57 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.18 2004/05/26 04:41:09 neilc Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -56,7 +56,7 @@ DefineAggregate(List *names, List *parameters)
 	char	   *initval = NULL;
 	Oid			baseTypeId;
 	Oid			transTypeId;
-	List	   *pl;
+	ListCell   *pl;
 
 	/* Convert list of names to a name and namespace */
 	aggNamespace = QualifiedNameGetCreationNamespace(names, &aggName);
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 5bb3c51dd35c1780de38ae5d49af54c140b1723d..40a28103c77c07199912b9d89f85fa25ae3e48a0 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.6 2003/11/29 19:51:47 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.7 2004/05/26 04:41:09 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -41,7 +41,9 @@ ExecRenameStmt(RenameStmt *stmt)
 	switch (stmt->renameType)
 	{
 		case OBJECT_AGGREGATE:
-			RenameAggregate(stmt->object, (TypeName *) lfirst(stmt->objarg), stmt->newname);
+			RenameAggregate(stmt->object,
+							(TypeName *) linitial(stmt->objarg),
+							stmt->newname);
 			break;
 
 		case OBJECT_CONVERSION:
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 0f6ff2d37e6e124f2d066ab3ad0c8632c78b44c7..4efaf653ede959e6f6407e9b0f749f92ce4eee41 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.72 2004/05/23 21:24:02 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.73 2004/05/26 04:41:09 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -207,9 +207,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
 	 */
 	if (vacstmt->va_cols != NIL)
 	{
-		List	   *le;
+		ListCell   *le;
 
-		vacattrstats = (VacAttrStats **) palloc(length(vacstmt->va_cols) *
+		vacattrstats = (VacAttrStats **) palloc(list_length(vacstmt->va_cols) *
 												sizeof(VacAttrStats *));
 		tcnt = 0;
 		foreach(le, vacstmt->va_cols)
@@ -260,7 +260,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
 			thisdata->tupleFract = 1.0;		/* fix later if partial */
 			if (indexInfo->ii_Expressions != NIL && vacstmt->va_cols == NIL)
 			{
-				List	   *indexprs = indexInfo->ii_Expressions;
+				ListCell   *indexpr_item = list_head(indexInfo->ii_Expressions);
 
 				thisdata->vacattrstats = (VacAttrStats **)
 					palloc(indexInfo->ii_NumIndexAttrs * sizeof(VacAttrStats *));
@@ -274,10 +274,10 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
 						/* Found an index expression */
 						Node	   *indexkey;
 
-						if (indexprs == NIL)	/* shouldn't happen */
+						if (indexpr_item == NULL)	/* shouldn't happen */
 							elog(ERROR, "too few entries in indexprs list");
-						indexkey = (Node *) lfirst(indexprs);
-						indexprs = lnext(indexprs);
+						indexkey = (Node *) lfirst(indexpr_item);
+						indexpr_item = lnext(indexpr_item);
 
 						/*
 						 * Can't analyze if the opclass uses a storage type
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 15d7c0aae5c191486cc8243caee65f7a66c8f447..847f73ff06ade9b0defbe791015ec0507b9d706d 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.111 2004/05/23 03:50:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.112 2004/05/26 04:41:10 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -932,7 +932,7 @@ NotifyMyFrontEnd(char *relname, int32 listenerPID)
 static bool
 AsyncExistsPendingNotify(const char *relname)
 {
-	List	   *p;
+	ListCell   *p;
 
 	foreach(p, pendingNotifies)
 	{
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 168ae749fa08f748f539625aca7f50851bb583d9..d9c4397176b9f50ac2985bf0a7cb892626910497 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.123 2004/05/08 00:34:49 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.124 2004/05/26 04:41:10 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -103,7 +103,7 @@ cluster(ClusterStmt *stmt)
 
 		if (stmt->indexname == NULL)
 		{
-			List	   *index;
+			ListCell   *index;
 
 			/* We need to find the index that has indisclustered set. */
 			foreach(index, RelationGetIndexList(rel))
@@ -111,7 +111,7 @@ cluster(ClusterStmt *stmt)
 				HeapTuple	idxtuple;
 				Form_pg_index indexForm;
 
-				indexOid = lfirsto(index);
+				indexOid = lfirst_oid(index);
 				idxtuple = SearchSysCache(INDEXRELID,
 										  ObjectIdGetDatum(indexOid),
 										  0, 0, 0);
@@ -165,8 +165,8 @@ cluster(ClusterStmt *stmt)
 		 * tables that have some index with indisclustered set.
 		 */
 		MemoryContext cluster_context;
-		List	   *rv,
-				   *rvs;
+		List	   *rvs;
+		ListCell   *rv;
 
 		/*
 		 * We cannot run this form of CLUSTER inside a user transaction
@@ -408,7 +408,7 @@ mark_index_clustered(Relation rel, Oid indexOid)
 	HeapTuple	indexTuple;
 	Form_pg_index indexForm;
 	Relation	pg_index;
-	List	   *index;
+	ListCell   *index;
 
 	/*
 	 * If the index is already marked clustered, no need to do anything.
@@ -438,7 +438,7 @@ mark_index_clustered(Relation rel, Oid indexOid)
 
 	foreach(index, RelationGetIndexList(rel))
 	{
-		Oid		thisIndexOid = lfirsto(index);
+		Oid		thisIndexOid = lfirst_oid(index);
 
 		indexTuple = SearchSysCacheCopy(INDEXRELID,
 										ObjectIdGetDatum(thisIndexOid),
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 423ab97570ae4289df00e50da97f22ff4c30f03e..4c0d65038b2336e600734b4f824c6dcbe50f2f71 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -7,7 +7,7 @@
  * Copyright (c) 1996-2003, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.76 2004/03/08 21:35:59 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.77 2004/05/26 04:41:10 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -379,11 +379,11 @@ CommentAttribute(List *qualname, char *comment)
 	AttrNumber	attnum;
 
 	/* Separate relname and attr name */
-	nnames = length(qualname);
+	nnames = list_length(qualname);
 	if (nnames < 2)				/* parser messed up */
 		elog(ERROR, "must specify relation and attribute");
-	relname = ltruncate(nnames - 1, listCopy(qualname));
-	attrname = strVal(llast(qualname));
+	relname = list_truncate(list_copy(qualname), nnames - 1);
+	attrname = strVal(lfirst(list_tail(qualname)));
 
 	/* Open the containing relation to ensure it won't go away meanwhile */
 	rel = makeRangeVarFromNameList(relname);
@@ -429,11 +429,11 @@ CommentDatabase(List *qualname, char *comment)
 	char	   *database;
 	Oid			oid;
 
-	if (length(qualname) != 1)
+	if (list_length(qualname) != 1)
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("database name may not be qualified")));
-	database = strVal(lfirst(qualname));
+	database = strVal(linitial(qualname));
 
 	/*
 	 * We cannot currently support cross-database comments (since other
@@ -493,11 +493,11 @@ CommentNamespace(List *qualname, char *comment)
 	Oid			classoid;
 	char	   *namespace;
 
-	if (length(qualname) != 1)
+	if (list_length(qualname) != 1)
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("schema name may not be qualified")));
-	namespace = strVal(lfirst(qualname));
+	namespace = strVal(linitial(qualname));
 
 	oid = GetSysCacheOid(NAMESPACENAME,
 						 CStringGetDatum(namespace),
@@ -548,7 +548,7 @@ CommentRule(List *qualname, char *comment)
 	AclResult	aclcheck;
 
 	/* Separate relname and trig name */
-	nnames = length(qualname);
+	nnames = list_length(qualname);
 	if (nnames == 1)
 	{
 		/* Old-style: only a rule name is given */
@@ -556,7 +556,7 @@ CommentRule(List *qualname, char *comment)
 		HeapScanDesc scanDesc;
 		ScanKeyData scanKeyData;
 
-		rulename = strVal(lfirst(qualname));
+		rulename = strVal(linitial(qualname));
 
 		/* Search pg_rewrite for such a rule */
 		ScanKeyInit(&scanKeyData,
@@ -599,8 +599,8 @@ CommentRule(List *qualname, char *comment)
 	{
 		/* New-style: rule and relname both provided */
 		Assert(nnames >= 2);
-		relname = ltruncate(nnames - 1, listCopy(qualname));
-		rulename = strVal(llast(qualname));
+		relname = list_truncate(list_copy(qualname), nnames - 1);
+		rulename = strVal(lfirst(list_tail(qualname)));
 
 		/* Open the owning relation to ensure it won't go away meanwhile */
 		rel = makeRangeVarFromNameList(relname);
@@ -683,7 +683,7 @@ CommentType(List *typename, char *comment)
 static void
 CommentAggregate(List *aggregate, List *arguments, char *comment)
 {
-	TypeName   *aggtype = (TypeName *) lfirst(arguments);
+	TypeName   *aggtype = (TypeName *) linitial(arguments);
 	Oid			baseoid,
 				oid;
 
@@ -750,7 +750,7 @@ CommentProc(List *function, List *arguments, char *comment)
 static void
 CommentOperator(List *opername, List *arguments, char *comment)
 {
-	TypeName   *typenode1 = (TypeName *) lfirst(arguments);
+	TypeName   *typenode1 = (TypeName *) linitial(arguments);
 	TypeName   *typenode2 = (TypeName *) lsecond(arguments);
 	Oid			oid;
 	Oid			classoid;
@@ -794,11 +794,11 @@ CommentTrigger(List *qualname, char *comment)
 	Oid			oid;
 
 	/* Separate relname and trig name */
-	nnames = length(qualname);
+	nnames = list_length(qualname);
 	if (nnames < 2)				/* parser messed up */
 		elog(ERROR, "must specify relation and trigger");
-	relname = ltruncate(nnames - 1, listCopy(qualname));
-	trigname = strVal(llast(qualname));
+	relname = list_truncate(list_copy(qualname), nnames - 1);
+	trigname = strVal(lfirst(list_tail(qualname)));
 
 	/* Open the owning relation to ensure it won't go away meanwhile */
 	rel = makeRangeVarFromNameList(relname);
@@ -872,11 +872,11 @@ CommentConstraint(List *qualname, char *comment)
 	Oid			conOid = InvalidOid;
 
 	/* Separate relname and constraint name */
-	nnames = length(qualname);
+	nnames = list_length(qualname);
 	if (nnames < 2)				/* parser messed up */
 		elog(ERROR, "must specify relation and constraint");
-	relName = ltruncate(nnames - 1, listCopy(qualname));
-	conName = strVal(llast(qualname));
+	relName = list_truncate(list_copy(qualname), nnames - 1);
+	conName = strVal(lfirst(list_tail(qualname)));
 
 	/* Open the owning relation to ensure it won't go away meanwhile */
 	rel = makeRangeVarFromNameList(relName);
@@ -985,11 +985,11 @@ CommentLanguage(List *qualname, char *comment)
 	Oid			classoid;
 	char	   *language;
 
-	if (length(qualname) != 1)
+	if (list_length(qualname) != 1)
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("language name may not be qualified")));
-	language = strVal(lfirst(qualname));
+	language = strVal(linitial(qualname));
 
 	oid = GetSysCacheOid(LANGNAME,
 						 CStringGetDatum(language),
@@ -1032,8 +1032,8 @@ CommentOpClass(List *qualname, List *arguments, char *comment)
 	Oid			classoid;
 	HeapTuple	tuple;
 
-	Assert(length(arguments) == 1);
-	amname = strVal(lfirst(arguments));
+	Assert(list_length(arguments) == 1);
+	amname = strVal(linitial(arguments));
 
 	/*
 	 * Get the access method's OID.
@@ -1118,8 +1118,8 @@ CommentLargeObject(List *qualname, char *comment)
 	Oid			classoid;
 	Node	   *node; 
 
-	Assert(length(qualname) == 1);
-	node = (Node *) lfirst(qualname);
+	Assert(list_length(qualname) == 1);
+	node = (Node *) linitial(qualname);
 
 	switch (nodeTag(node))
 	{
@@ -1176,11 +1176,11 @@ CommentCast(List *qualname, List *arguments, char *comment)
 	Oid			castOid;
 	Oid			classoid;
 
-	Assert(length(qualname) == 1);
-	sourcetype = (TypeName *) lfirst(qualname);
+	Assert(list_length(qualname) == 1);
+	sourcetype = (TypeName *) linitial(qualname);
 	Assert(IsA(sourcetype, TypeName));
-	Assert(length(arguments) == 1);
-	targettype = (TypeName *) lfirst(arguments);
+	Assert(list_length(arguments) == 1);
+	targettype = (TypeName *) linitial(arguments);
 	Assert(IsA(targettype, TypeName));
 	
 	sourcetypeid = typenameTypeId(sourcetype);
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 74025ad041bea088ce9da915e41d394a68d9b302..a666516fb3994d97780b2ceb4a726fb7045eaccb 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.223 2004/04/21 00:34:18 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.224 2004/05/26 04:41:10 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -685,7 +685,7 @@ DoCopy(const CopyStmt *stmt)
 	char	   *filename = stmt->filename;
 	bool		is_from = stmt->is_from;
 	bool		pipe = (stmt->filename == NULL);
-	List	   *option;
+	ListCell   *option;
 	List	   *attnamelist = stmt->attlist;
 	List	   *attnumlist;
 	bool		binary = false;
@@ -934,15 +934,15 @@ DoCopy(const CopyStmt *stmt)
 	{
 		TupleDesc	tupDesc = RelationGetDescr(rel);
 		Form_pg_attribute *attr = tupDesc->attrs;
-		List	   *cur;
+		ListCell   *cur;
 
 		force_quote_atts = CopyGetAttnums(rel, force_quote);
 
 		foreach(cur, force_quote_atts)
 		{
-			int			attnum = lfirsti(cur);
+			int			attnum = lfirst_int(cur);
 
-			if (!intMember(attnum, attnumlist))
+			if (!list_member_int(attnumlist, attnum))
 				ereport(ERROR,
 						(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
 						 errmsg("FORCE QUOTE column \"%s\" not referenced by COPY",
@@ -955,7 +955,7 @@ DoCopy(const CopyStmt *stmt)
 	 */
 	if (force_notnull)
 	{
-		List	   *cur;
+		ListCell   *cur;
 		TupleDesc	tupDesc = RelationGetDescr(rel);
 		Form_pg_attribute *attr = tupDesc->attrs;
 
@@ -963,9 +963,9 @@ DoCopy(const CopyStmt *stmt)
 
 		foreach(cur, force_notnull_atts)
 		{
-			int			attnum = lfirsti(cur);
+			int			attnum = lfirst_int(cur);
 
-			if (!intMember(attnum, attnumlist))
+			if (!list_member_int(attnumlist, attnum))
 				ereport(ERROR,
 						(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
 						 errmsg("FORCE NOT NULL column \"%s\" not referenced by COPY",
@@ -1011,7 +1011,7 @@ DoCopy(const CopyStmt *stmt)
 		if (pipe)
 		{
 			if (whereToSendOutput == Remote)
-				ReceiveCopyBegin(binary, length(attnumlist));
+				ReceiveCopyBegin(binary, list_length(attnumlist));
 			else
 				copy_file = stdin;
 		}
@@ -1062,7 +1062,7 @@ DoCopy(const CopyStmt *stmt)
 		if (pipe)
 		{
 			if (whereToSendOutput == Remote)
-				SendCopyBegin(binary, length(attnumlist));
+				SendCopyBegin(binary, list_length(attnumlist));
 			else
 				copy_file = stdout;
 		}
@@ -1147,14 +1147,14 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
 	bool	   *isvarlena;
 	char	   *string;
 	Snapshot	mySnapshot;
-	List	   *cur;
+	ListCell   *cur;
 	MemoryContext oldcontext;
 	MemoryContext mycontext;
 
 	tupDesc = rel->rd_att;
 	attr = tupDesc->attrs;
 	num_phys_attrs = tupDesc->natts;
-	attr_count = length(attnumlist);
+	attr_count = list_length(attnumlist);
 
 	/*
 	 * Get info about the columns we need to process.
@@ -1167,7 +1167,7 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
 	force_quote = (bool *) palloc((num_phys_attrs + 1) * sizeof(bool));
 	foreach(cur, attnumlist)
 	{
-		int			attnum = lfirsti(cur);
+		int			attnum = lfirst_int(cur);
 		Oid			out_func_oid;
 		
 		if (binary)
@@ -1180,7 +1180,7 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
 							  &isvarlena[attnum - 1]);
 		fmgr_info(out_func_oid, &out_functions[attnum - 1]);
 
-		if (intMember(attnum, force_quote_atts))
+		if (list_member_int(force_quote_atts, attnum))
 			force_quote[attnum - 1] = true;
 		else
 			force_quote[attnum - 1] = false;
@@ -1266,7 +1266,7 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids,
 
 		foreach(cur, attnumlist)
 		{
-			int			attnum = lfirsti(cur);
+			int			attnum = lfirst_int(cur);
 			Datum		value;
 			bool		isnull;
 
@@ -1451,7 +1451,6 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
 	bool		hasConstraints = false;
 	int			attnum;
 	int			i;
-	List	   *cur;
 	Oid			in_func_oid;
 	Datum	   *values;
 	char	   *nulls;
@@ -1471,7 +1470,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
 	tupDesc = RelationGetDescr(rel);
 	attr = tupDesc->attrs;
 	num_phys_attrs = tupDesc->natts;
-	attr_count = length(attnumlist);
+	attr_count = list_length(attnumlist);
 	num_defaults = 0;
 
 	/*
@@ -1526,13 +1525,13 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
 							 &in_func_oid, &elements[attnum - 1]);
 		fmgr_info(in_func_oid, &in_functions[attnum - 1]);
 
-		if (intMember(attnum, force_notnull_atts))
+		if (list_member_int(force_notnull_atts, attnum))
 			force_notnull[attnum - 1] = true;
 		else
 			force_notnull[attnum - 1] = false;
 		
 		/* Get default info if needed */
-		if (!intMember(attnum, attnumlist))
+		if (!list_member_int(attnumlist, attnum))
 		{
 			/* attribute is NOT to be copied from input */
 			/* use default value if one exists */
@@ -1681,6 +1680,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
 		{
 			CopyReadResult result = NORMAL_ATTR;
 			char	   *string;
+			ListCell   *cur;
 
 			/* Actually read the line into memory here */
 			done = CopyReadLine();
@@ -1722,7 +1722,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
 			 */
 			foreach(cur, attnumlist)
 			{
-				int			attnum = lfirsti(cur);
+				int			attnum = lfirst_int(cur);
 				int			m = attnum - 1;
 
 				/*
@@ -1783,6 +1783,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
 		{
 			/* binary */
 			int16		fld_count;
+			ListCell   *cur;
 
 			fld_count = CopyGetInt16();
 			if (CopyGetEof() || fld_count == -1)
@@ -1815,7 +1816,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
 			i = 0;
 			foreach(cur, attnumlist)
 			{
-				int			attnum = lfirsti(cur);
+				int			attnum = lfirst_int(cur);
 				int			m = attnum - 1;
 
 				copy_attname = NameStr(attr[m]->attname);
@@ -2642,13 +2643,13 @@ CopyGetAttnums(Relation rel, List *attnamelist)
 		{
 			if (attr[i]->attisdropped)
 				continue;
-			attnums = lappendi(attnums, i + 1);
+			attnums = lappend_int(attnums, i + 1);
 		}
 	}
 	else
 	{
 		/* Validate the user-supplied list and extract attnums */
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, attnamelist)
 		{
@@ -2659,12 +2660,12 @@ CopyGetAttnums(Relation rel, List *attnamelist)
 			/* Note we disallow system columns here */
 			attnum = attnameAttNum(rel, name, false);
 			/* Check for duplicates */
-			if (intMember(attnum, attnums))
+			if (list_member_int(attnums, attnum))
 				ereport(ERROR,
 						(errcode(ERRCODE_DUPLICATE_COLUMN),
 					  errmsg("column \"%s\" specified more than once",
 							 name)));
-			attnums = lappendi(attnums, attnum);
+			attnums = lappend_int(attnums, attnum);
 		}
 	}
 
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 038db4de70e22d042a07c4bafc31ce24b5b67f55..9114983e75de93856286663ed2738bf34f55381a 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.132 2004/04/19 17:42:57 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.133 2004/05/26 04:41:10 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -82,7 +82,7 @@ createdb(const CreatedbStmt *stmt)
 	char		new_record_nulls[Natts_pg_database];
 	Oid			dboid;
 	AclId		datdba;
-	List	   *option;
+	ListCell   *option;
 	DefElem    *downer = NULL;
 	DefElem    *dpath = NULL;
 	DefElem    *dtemplate = NULL;
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index e4a62b77308ffe6289cad333bfa5c81e3fc0b961..1a12674fa772fa4e82d931b7cc5d2bda149114bd 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.88 2004/05/14 16:11:25 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.89 2004/05/26 04:41:10 neilc Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -190,7 +190,7 @@ defGetQualifiedName(DefElem *def)
 			return (List *) def->arg;
 		case T_String:
 			/* Allow quoted name for backwards compatibility */
-			return makeList1(def->arg);
+			return list_make1(def->arg);
 		default:
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
@@ -223,7 +223,7 @@ defGetTypeName(DefElem *def)
 				/* Allow quoted typename for backwards compatibility */
 				TypeName   *n = makeNode(TypeName);
 
-				n->names = makeList1(def->arg);
+				n->names = list_make1(def->arg);
 				n->typmod = -1;
 				return n;
 			}
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index e2f3d4aa8136d10497418db50b134399e11be6fc..3658a00ea21f2bf4b4a7e6aa63c11d7f1bcf6cf2 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.120 2004/04/01 21:28:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.121 2004/05/26 04:41:10 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -72,7 +72,7 @@ ExplainQuery(ExplainStmt *stmt, DestReceiver *dest)
 	Query	   *query = stmt->query;
 	TupOutputState *tstate;
 	List	   *rewritten;
-	List	   *l;
+	ListCell   *l;
 
 	/* prepare for projection of tuples */
 	tstate = begin_tup_output_tupdesc(dest, ExplainResultDesc(stmt));
@@ -104,7 +104,7 @@ ExplainQuery(ExplainStmt *stmt, DestReceiver *dest)
 			{
 				ExplainOneQuery(lfirst(l), stmt, tstate);
 				/* put a blank line between plans */
-				if (lnext(l) != NIL)
+				if (lnext(l) != NULL)
 					do_text_output_oneline(tstate, "");
 			}
 		}
@@ -156,9 +156,9 @@ ExplainOneQuery(Query *query, ExplainStmt *stmt, TupOutputState *tstate)
 			/* Still need to rewrite cursor command */
 			Assert(query->commandType == CMD_SELECT);
 			rewritten = QueryRewrite(query);
-			if (length(rewritten) != 1)
+			if (list_length(rewritten) != 1)
 				elog(ERROR, "unexpected rewrite result");
-			query = (Query *) lfirst(rewritten);
+			query = (Query *) linitial(rewritten);
 			Assert(query->commandType == CMD_SELECT);
 			/* do not actually execute the underlying query! */
 			stmt->analyze = false;
@@ -317,7 +317,7 @@ explain_outNode(StringInfo str,
 				Plan *outer_plan,
 				int indent, ExplainState *es)
 {
-	List	   *l;
+	ListCell	*l;
 	char	   *pname;
 	int			i;
 
@@ -491,7 +491,7 @@ explain_outNode(StringInfo str,
 			{
 				Relation	relation;
 
-				relation = index_open(lfirsto(l));
+				relation = index_open(lfirst_oid(l));
 				appendStringInfo(str, "%s%s",
 								 (++i > 1) ? ", " : "",
 					quote_identifier(RelationGetRelationName(relation)));
@@ -699,7 +699,7 @@ explain_outNode(StringInfo str,
 	if (plan->initPlan)
 	{
 		List	   *saved_rtable = es->rtable;
-		List	   *lst;
+		ListCell   *lst;
 
 		for (i = 0; i < indent; i++)
 			appendStringInfo(str, "  ");
@@ -749,7 +749,7 @@ explain_outNode(StringInfo str,
 	{
 		Append	   *appendplan = (Append *) plan;
 		AppendState *appendstate = (AppendState *) planstate;
-		List	   *lst;
+		ListCell   *lst;
 		int			j;
 
 		j = 0;
@@ -797,7 +797,7 @@ explain_outNode(StringInfo str,
 	if (planstate->subPlan)
 	{
 		List	   *saved_rtable = es->rtable;
-		List	   *lst;
+		ListCell   *lst;
 
 		for (i = 0; i < indent; i++)
 			appendStringInfo(str, "  ");
@@ -839,11 +839,8 @@ show_scan_qual(List *qual, bool is_or_qual, const char *qlabel,
 	/* No work if empty qual */
 	if (qual == NIL)
 		return;
-	if (is_or_qual)
-	{
-		if (lfirst(qual) == NIL && lnext(qual) == NIL)
-			return;
-	}
+	if (is_or_qual && list_length(qual) == 1 && linitial(qual) == NIL)
+		return;
 
 	/* Fix qual --- indexqual requires different processing */
 	if (is_or_qual)
@@ -852,7 +849,7 @@ show_scan_qual(List *qual, bool is_or_qual, const char *qlabel,
 		node = (Node *) make_ands_explicit(qual);
 
 	/* Generate deparse context */
-	Assert(scanrelid > 0 && scanrelid <= length(es->rtable));
+	Assert(scanrelid > 0 && scanrelid <= list_length(es->rtable));
 	rte = rt_fetch(scanrelid, es->rtable);
 	scancontext = deparse_context_for_rte(rte);
 
@@ -984,7 +981,7 @@ show_sort_keys(List *tlist, int nkeys, AttrNumber *keycols,
 		context = deparse_context_for_plan(0, NULL,
 										   0, NULL,
 										   es->rtable);
-		useprefix = length(es->rtable) > 1;
+		useprefix = list_length(es->rtable) > 1;
 	}
 	bms_free(varnos);
 
@@ -1017,17 +1014,16 @@ make_ors_ands_explicit(List *orclauses)
 {
 	if (orclauses == NIL)
 		return NULL;			/* probably can't happen */
-	else if (lnext(orclauses) == NIL)
-		return (Node *) make_ands_explicit(lfirst(orclauses));
+	else if (list_length(orclauses) == 1)
+		return (Node *) make_ands_explicit(linitial(orclauses));
 	else
 	{
-		FastList	args;
-		List	   *orptr;
+		List	   *args = NIL;
+		ListCell   *orptr;
 
-		FastListInit(&args);
 		foreach(orptr, orclauses)
-			FastAppend(&args, make_ands_explicit(lfirst(orptr)));
+			args = lappend(args, make_ands_explicit(lfirst(orptr)));
 
-		return (Node *) make_orclause(FastListValue(&args));
+		return (Node *) make_orclause(args);
 	}
 }
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index c118e8e3b5e7a615e7d64e445c5962a5d8f0a779..757869a925ae89bb9e7e445ddcc724e227cf792f 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.46 2004/05/14 16:11:25 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.47 2004/05/26 04:41:11 neilc Exp $
  *
  * DESCRIPTION
  *	  These routines take the parse tree and pick out the
@@ -137,7 +137,7 @@ examine_parameter_list(List *parameter, Oid languageOid,
 					   Oid *parameterTypes, const char *parameterNames[])
 {
 	int			parameterCount = 0;
-	List	   *x;
+	ListCell   *x;
 
 	MemSet(parameterTypes, 0, FUNC_MAX_ARGS * sizeof(Oid));
 	MemSet(parameterNames, 0, FUNC_MAX_ARGS * sizeof(char *));
@@ -202,14 +202,14 @@ examine_parameter_list(List *parameter, Oid languageOid,
  */
 
 static void
-compute_attributes_sql_style(const List *options,
+compute_attributes_sql_style(List *options,
 							 List **as,
 							 char **language,
 							 char *volatility_p,
 							 bool *strict_p,
 							 bool *security_definer)
 {
-	const List *option;
+	ListCell   *option;
 	DefElem    *as_item = NULL;
 	DefElem    *language_item = NULL;
 	DefElem    *volatility_item = NULL;
@@ -322,7 +322,7 @@ compute_attributes_sql_style(const List *options,
 static void
 compute_attributes_with_style(List *parameters, bool *isStrict_p, char *volatility_p)
 {
-	List	   *pl;
+	ListCell   *pl;
 
 	foreach(pl, parameters)
 	{
@@ -357,7 +357,7 @@ compute_attributes_with_style(List *parameters, bool *isStrict_p, char *volatili
  */
 
 static void
-interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
+interpret_AS_clause(Oid languageOid, const char *languageName, List *as,
 					char **prosrc_str_p, char **probin_str_p)
 {
 	Assert(as != NIL);
@@ -368,8 +368,8 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
 		 * For "C" language, store the file name in probin and, when
 		 * given, the link symbol name in prosrc.
 		 */
-		*probin_str_p = strVal(lfirst(as));
-		if (lnext(as) == NULL)
+		*probin_str_p = strVal(linitial(as));
+		if (list_length(as) == 1)
 			*prosrc_str_p = "-";
 		else
 			*prosrc_str_p = strVal(lsecond(as));
@@ -377,10 +377,10 @@ interpret_AS_clause(Oid languageOid, const char *languageName, const List *as,
 	else
 	{
 		/* Everything else wants the given string in prosrc. */
-		*prosrc_str_p = strVal(lfirst(as));
+		*prosrc_str_p = strVal(linitial(as));
 		*probin_str_p = "-";
 
-		if (lnext(as) != NIL)
+		if (list_length(as) != 1)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
 					 errmsg("only one AS item needed for language \"%s\"",
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 448f99e1d37f54761b9089f0b360ab425d293b76..1fe8e58e585525e85b2e897fd66d6c776d28923e 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.119 2004/05/08 00:34:49 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.120 2004/05/26 04:41:11 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -109,7 +109,7 @@ DefineIndex(RangeVar *heapRelation,
 	/*
 	 * count attributes in index
 	 */
-	numberOfAttributes = length(attributeList);
+	numberOfAttributes = list_length(attributeList);
 	if (numberOfAttributes <= 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
@@ -165,7 +165,7 @@ DefineIndex(RangeVar *heapRelation,
 												namespaceId);
 		else
 		{
-			IndexElem  *iparam = (IndexElem *) lfirst(attributeList);
+			IndexElem  *iparam = (IndexElem *) linitial(attributeList);
 
 			indexRelationName = CreateIndexName(RelationGetRelationName(rel),
 												iparam->name,
@@ -208,7 +208,7 @@ DefineIndex(RangeVar *heapRelation,
 	 */
 	if (rangetable != NIL)
 	{
-		if (length(rangetable) != 1 || getrelid(1, rangetable) != relationId)
+		if (list_length(rangetable) != 1 || getrelid(1, rangetable) != relationId)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
 					 errmsg("index expressions and predicates may refer only to the table being indexed")));
@@ -226,7 +226,7 @@ DefineIndex(RangeVar *heapRelation,
 	if (primary)
 	{
 		List	   *cmds;
-		List	   *keys;
+		ListCell   *keys;
 
 		/*
 		 * If ALTER TABLE, check that there isn't already a PRIMARY KEY.
@@ -399,7 +399,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
 				  Oid accessMethodId,
 				  bool isconstraint)
 {
-	List	   *rest;
+	ListCell   *rest;
 	int			attn = 0;
 
 	/*
@@ -516,9 +516,9 @@ GetIndexOpClass(List *opclass, Oid attrType,
 	 * Release 7.5 removes bigbox_ops (which was dead code for a long while
 	 * anyway).  tgl 2003/11/11
 	 */
-	if (length(opclass) == 1)
+	if (list_length(opclass) == 1)
 	{
-		char	   *claname = strVal(lfirst(opclass));
+		char	   *claname = strVal(linitial(opclass));
 
 		if (strcmp(claname, "network_ops") == 0 ||
 			strcmp(claname, "timespan_ops") == 0 ||
@@ -697,8 +697,8 @@ static bool
 relationHasPrimaryKey(Relation rel)
 {
 	bool		result = false;
-	List	   *indexoidlist,
-			   *indexoidscan;
+	List	   *indexoidlist;
+	ListCell   *indexoidscan;
 
 	/*
 	 * Get the list of index OIDs for the table from the relcache, and
@@ -709,7 +709,7 @@ relationHasPrimaryKey(Relation rel)
 
 	foreach(indexoidscan, indexoidlist)
 	{
-		Oid			indexoid = lfirsto(indexoidscan);
+		Oid			indexoid = lfirst_oid(indexoidscan);
 		HeapTuple	indexTuple;
 
 		indexTuple = SearchSysCache(INDEXRELID,
@@ -723,7 +723,7 @@ relationHasPrimaryKey(Relation rel)
 			break;
 	}
 
-	freeList(indexoidlist);
+	list_free(indexoidlist);
 
 	return result;
 }
@@ -843,12 +843,13 @@ void
 ReindexDatabase(const char *dbname, bool force /* currently unused */,
 				bool all)
 {
-	Relation	relationRelation;
+	Relation	 relationRelation;
 	HeapScanDesc scan;
-	HeapTuple	tuple;
+	HeapTuple	 tuple;
 	MemoryContext private_context;
 	MemoryContext old;
-	List	   *relids = NIL;
+	List		*relids = NIL;
+	ListCell	*l;
 
 	AssertArg(dbname);
 
@@ -887,7 +888,7 @@ ReindexDatabase(const char *dbname, bool force /* currently unused */,
 	 * reindexing itself will try to update pg_class.
 	 */
 	old = MemoryContextSwitchTo(private_context);
-	relids = lappendo(relids, RelOid_pg_class);
+	relids = lappend_oid(relids, RelOid_pg_class);
 	MemoryContextSwitchTo(old);
 
 	/*
@@ -921,7 +922,7 @@ ReindexDatabase(const char *dbname, bool force /* currently unused */,
 			continue;			/* got it already */
 
 		old = MemoryContextSwitchTo(private_context);
-		relids = lappendo(relids, HeapTupleGetOid(tuple));
+		relids = lappend_oid(relids, HeapTupleGetOid(tuple));
 		MemoryContextSwitchTo(old);
 	}
 	heap_endscan(scan);
@@ -929,9 +930,9 @@ ReindexDatabase(const char *dbname, bool force /* currently unused */,
 
 	/* Now reindex each rel in a separate transaction */
 	CommitTransactionCommand();
-	while (relids)
+	foreach(l, relids)
 	{
-		Oid		relid = lfirsto(relids);
+		Oid		relid = lfirst_oid(l);
 
 		StartTransactionCommand();
 		SetQuerySnapshot();		/* might be needed for functions in
@@ -941,7 +942,6 @@ ReindexDatabase(const char *dbname, bool force /* currently unused */,
 					(errmsg("table \"%s\" was reindexed",
 							get_rel_name(relid))));
 		CommitTransactionCommand();
-		relids = lnext(relids);
 	}
 	StartTransactionCommand();
 
diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c
index 58bee42f8fe8360d7539801285d9c7804edd1fe6..7ab0687e983b42308f4dcd9211214918e3eed3bc 100644
--- a/src/backend/commands/lockcmds.c
+++ b/src/backend/commands/lockcmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/lockcmds.c,v 1.9 2004/03/11 01:47:35 ishii Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/lockcmds.c,v 1.10 2004/05/26 04:41:11 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,7 +28,7 @@
 void
 LockTableCommand(LockStmt *lockstmt)
 {
-	List	   *p;
+	ListCell   *p;
 
 	/*
 	 * Iterate over the list and open, lock, and close the relations one
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index d3551a7349f02ae19a8c71d6798fa6a7d1427db0..db5c2ccabc92a67927dcbf8a391a79848a99469a 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.24 2003/11/29 19:51:47 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.25 2004/05/26 04:41:11 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -77,7 +77,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
 				numProcs;		/* amsupport value */
 	List	   *operators;		/* OpClassMember list for operators */
 	List	   *procedures;		/* OpClassMember list for support procs */
-	List	   *l;
+	ListCell   *l;
 	Relation	rel;
 	HeapTuple	tup;
 	Datum		values[Natts_pg_opclass];
@@ -168,7 +168,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
 									item->number, numOperators)));
 				if (item->args != NIL)
 				{
-					TypeName   *typeName1 = (TypeName *) lfirst(item->args);
+					TypeName   *typeName1 = (TypeName *) linitial(item->args);
 					TypeName   *typeName2 = (TypeName *) lsecond(item->args);
 
 					operOid = LookupOperNameTypeNames(item->name,
@@ -506,7 +506,7 @@ assignProcSubtype(Oid amoid, Oid typeoid, Oid procOid)
 static void
 addClassMember(List **list, OpClassMember *member, bool isProc)
 {
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, *list)
 	{
@@ -540,7 +540,7 @@ storeOperators(Oid opclassoid, List *operators)
 	Datum		values[Natts_pg_amop];
 	char		nulls[Natts_pg_amop];
 	HeapTuple	tup;
-	List	   *l;
+	ListCell   *l;
 	int			i;
 
 	rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock);
@@ -584,7 +584,7 @@ storeProcedures(Oid opclassoid, List *procedures)
 	Datum		values[Natts_pg_amproc];
 	char		nulls[Natts_pg_amproc];
 	HeapTuple	tup;
-	List	   *l;
+	ListCell   *l;
 	int			i;
 
 	rel = heap_openr(AccessMethodProcedureRelationName, RowExclusiveLock);
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index a198f51eeebe09d34825a83dad62e88437bae9f5..d2ffae2ce56ea39c94b54b5fcc36b440b43f9fa9 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.15 2004/05/14 16:11:25 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.16 2004/05/26 04:41:11 neilc Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -79,7 +79,7 @@ DefineOperator(List *names, List *parameters)
 	List	   *rightSortName = NIL;	/* optional right sort operator */
 	List	   *ltCompareName = NIL;	/* optional < compare operator */
 	List	   *gtCompareName = NIL;	/* optional > compare operator */
-	List	   *pl;
+	ListCell   *pl;
 
 	/* Convert list of names to a name and namespace */
 	oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName);
@@ -167,13 +167,13 @@ DefineOperator(List *names, List *parameters)
 	if (canMerge)
 	{
 		if (!leftSortName)
-			leftSortName = makeList1(makeString("<"));
+			leftSortName = list_make1(makeString("<"));
 		if (!rightSortName)
-			rightSortName = makeList1(makeString("<"));
+			rightSortName = list_make1(makeString("<"));
 		if (!ltCompareName)
-			ltCompareName = makeList1(makeString("<"));
+			ltCompareName = list_make1(makeString("<"));
 		if (!gtCompareName)
-			gtCompareName = makeList1(makeString(">"));
+			gtCompareName = list_make1(makeString(">"));
 	}
 
 	/*
@@ -206,7 +206,7 @@ void
 RemoveOperator(RemoveOperStmt *stmt)
 {
 	List	   *operatorName = stmt->opname;
-	TypeName   *typeName1 = (TypeName *) lfirst(stmt->args);
+	TypeName   *typeName1 = (TypeName *) linitial(stmt->args);
 	TypeName   *typeName2 = (TypeName *) lsecond(stmt->args);
 	Oid			operOid;
 	HeapTuple	tup;
diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c
index 855c9391c18e4405b07d43060ad8f5b3a74bcb31..d2fa894a76ec4139eb7d11c347bbe445b62b9458 100644
--- a/src/backend/commands/portalcmds.c
+++ b/src/backend/commands/portalcmds.c
@@ -14,7 +14,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.26 2004/03/21 22:29:10 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/portalcmds.c,v 1.27 2004/05/26 04:41:11 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -68,9 +68,9 @@ PerformCursorOpen(DeclareCursorStmt *stmt)
 	 * strange.
 	 */
 	rewritten = QueryRewrite((Query *) stmt->query);
-	if (length(rewritten) != 1 || !IsA(lfirst(rewritten), Query))
+	if (list_length(rewritten) != 1 || !IsA(linitial(rewritten), Query))
 		elog(ERROR, "unexpected rewrite result");
-	query = (Query *) lfirst(rewritten);
+	query = (Query *) linitial(rewritten);
 	if (query->commandType != CMD_SELECT)
 		elog(ERROR, "unexpected rewrite result");
 
@@ -100,8 +100,8 @@ PerformCursorOpen(DeclareCursorStmt *stmt)
 	PortalDefineQuery(portal,
 					  NULL,		/* unfortunately don't have sourceText */
 					  "SELECT", /* cursor's query is always a SELECT */
-					  makeList1(query),
-					  makeList1(plan),
+					  list_make1(query),
+					  list_make1(plan),
 					  PortalGetHeapMemory(portal));
 
 	MemoryContextSwitchTo(oldContext);
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index d85d41c1ec7999b4c3a6ae7196c445db05c182b9..083ad2af5e78938ecae0500449f4db120c0397b5 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -10,7 +10,7 @@
  * Copyright (c) 2002-2003, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.26 2004/04/22 02:58:20 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.27 2004/05/26 04:41:11 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -125,7 +125,7 @@ ExecuteQuery(ExecuteStmt *stmt, DestReceiver *dest, char *completionTag)
 	plan_list = entry->plan_list;
 	qcontext = entry->context;
 
-	Assert(length(query_list) == length(plan_list));
+	Assert(list_length(query_list) == list_length(plan_list));
 
 	/* Evaluate parameters, if any */
 	if (entry->argtype_list != NIL)
@@ -162,11 +162,11 @@ ExecuteQuery(ExecuteStmt *stmt, DestReceiver *dest, char *completionTag)
 		plan_list = copyObject(plan_list);
 		qcontext = PortalGetHeapMemory(portal);
 
-		if (length(query_list) != 1)
+		if (list_length(query_list) != 1)
 			ereport(ERROR,
 					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 					 errmsg("prepared statement is not a SELECT")));
-		query = (Query *) lfirst(query_list);
+		query = (Query *) linitial(query_list);
 		if (query->commandType != CMD_SELECT)
 			ereport(ERROR,
 					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -208,14 +208,14 @@ ExecuteQuery(ExecuteStmt *stmt, DestReceiver *dest, char *completionTag)
 static ParamListInfo
 EvaluateParams(EState *estate, List *params, List *argtypes)
 {
-	int			nargs = length(argtypes);
+	int			nargs = list_length(argtypes);
 	ParamListInfo paramLI;
 	List	   *exprstates;
-	List	   *l;
+	ListCell   *l;
 	int			i = 0;
 
 	/* Parser should have caught this error, but check for safety */
-	if (length(params) != nargs)
+	if (list_length(params) != nargs)
 		elog(ERROR, "wrong number of arguments");
 
 	exprstates = (List *) ExecPrepareExpr((Expr *) params, estate);
@@ -326,7 +326,7 @@ StorePreparedStatement(const char *stmt_name,
 	qstring = query_string ? pstrdup(query_string) : NULL;
 	query_list = (List *) copyObject(query_list);
 	plan_list = (List *) copyObject(plan_list);
-	argtype_list = listCopy(argtype_list);
+	argtype_list = list_copy(argtype_list);
 
 	/* Now we can add entry to hash table */
 	entry = (PreparedStatement *) hash_search(prepared_queries,
@@ -419,11 +419,11 @@ FetchPreparedStatementResultDesc(PreparedStatement *stmt)
 	switch (ChoosePortalStrategy(stmt->query_list))
 	{
 		case PORTAL_ONE_SELECT:
-			query = (Query *) lfirst(stmt->query_list);
+			query = (Query *) linitial(stmt->query_list);
 			return ExecCleanTypeFromTL(query->targetList, false);
 
 		case PORTAL_UTIL_SELECT:
-			query = (Query *) lfirst(stmt->query_list);
+			query = (Query *) linitial(stmt->query_list);
 			return UtilityTupleDescriptor(query->utilityStmt);
 
 		case PORTAL_MULTI_QUERY:
@@ -478,8 +478,9 @@ ExplainExecuteQuery(ExplainStmt *stmt, TupOutputState *tstate)
 {
 	ExecuteStmt *execstmt = (ExecuteStmt *) stmt->query->utilityStmt;
 	PreparedStatement *entry;
-	List	   *l,
-			   *query_list,
+	ListCell   *q,
+			   *p;
+	List	   *query_list,
 			   *plan_list;
 	ParamListInfo paramLI = NULL;
 	EState	   *estate = NULL;
@@ -493,7 +494,7 @@ ExplainExecuteQuery(ExplainStmt *stmt, TupOutputState *tstate)
 	query_list = entry->query_list;
 	plan_list = entry->plan_list;
 
-	Assert(length(query_list) == length(plan_list));
+	Assert(list_length(query_list) == list_length(plan_list));
 
 	/* Evaluate parameters, if any */
 	if (entry->argtype_list != NIL)
@@ -508,14 +509,13 @@ ExplainExecuteQuery(ExplainStmt *stmt, TupOutputState *tstate)
 	}
 
 	/* Explain each query */
-	foreach(l, query_list)
+	forboth (q, query_list, p, plan_list)
 	{
-		Query	   *query = (Query *) lfirst(l);
-		Plan	   *plan = (Plan *) lfirst(plan_list);
+		Query	   *query = (Query *) lfirst(q);
+		Plan	   *plan = (Plan *) lfirst(p);
 		bool		is_last_query;
 
-		plan_list = lnext(plan_list);
-		is_last_query = (plan_list == NIL);
+		is_last_query = (lnext(p) == NULL);
 
 		if (query->commandType == CMD_UTILITY)
 		{
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 8af564cf74bff510439d052f4eb1658f1450164a..18a212271ea27160ec6a22af0acebf3b203aedaa 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.17 2003/11/29 19:51:47 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.18 2004/05/26 04:41:11 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,7 +42,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
 	const char *authId = stmt->authid;
 	Oid			namespaceId;
 	List	   *parsetree_list;
-	List	   *parsetree_item;
+	ListCell   *parsetree_item;
 	const char *owner_name;
 	AclId		owner_userid;
 	AclId		saved_userid;
@@ -129,8 +129,8 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
 	foreach(parsetree_item, parsetree_list)
 	{
 		Node	   *parsetree = (Node *) lfirst(parsetree_item);
-		List	   *querytree_list,
-				   *querytree_item;
+		List	   *querytree_list;
+		ListCell   *querytree_item;
 
 		querytree_list = parse_analyze(parsetree, NULL, 0);
 
@@ -166,11 +166,11 @@ RemoveSchema(List *names, DropBehavior behavior)
 	Oid			namespaceId;
 	ObjectAddress object;
 
-	if (length(names) != 1)
+	if (list_length(names) != 1)
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("schema name may not be qualified")));
-	namespaceName = strVal(lfirst(names));
+	namespaceName = strVal(linitial(names));
 
 	namespaceId = GetSysCacheOid(NAMESPACENAME,
 								 CStringGetDatum(namespaceName),
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 0ff1b386b5b167a7313314c0323315d22782c87a..351813b5decb055027428ac4444ac59b3ef8912a 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.110 2004/05/08 19:09:24 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.111 2004/05/26 04:41:11 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -862,7 +862,7 @@ init_params(List *options, Form_pg_sequence new, bool isInit)
 	DefElem    *min_value = NULL;
 	DefElem    *cache_value = NULL;
 	DefElem    *is_cycled = NULL;
-	List	   *option;
+	ListCell   *option;
 
 	foreach(option, options)
 	{
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index bf308141facbff0dce1625d6d4a0e0ae337209d0..431c4ac742ae20294e9fa34f23593f185416d438 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.107 2004/05/08 22:46:29 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.108 2004/05/26 04:41:12 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -262,7 +262,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
 	bool		localHasOids;
 	int			parentOidCount;
 	List	   *rawDefaults;
-	List	   *listptr;
+	ListCell   *listptr;
 	int			i;
 	AttrNumber	attnum;
 
@@ -320,7 +320,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
 
 	if (old_constraints != NIL)
 	{
-		ConstrCheck *check = (ConstrCheck *) palloc(length(old_constraints) *
+		ConstrCheck *check = (ConstrCheck *) palloc(list_length(old_constraints) *
 													sizeof(ConstrCheck));
 		int			ncheck = 0;
 		int			constr_name_ctr = 0;
@@ -634,7 +634,7 @@ static List *
 MergeAttributes(List *schema, List *supers, bool istemp,
 				List **supOids, List **supconstr, int *supOidCount)
 {
-	List	   *entry;
+	ListCell   *entry;
 	List	   *inhSchema = NIL;
 	List	   *parentOids = NIL;
 	List	   *constraints = NIL;
@@ -654,9 +654,9 @@ MergeAttributes(List *schema, List *supers, bool istemp,
 	foreach(entry, schema)
 	{
 		ColumnDef  *coldef = lfirst(entry);
-		List	   *rest;
+		ListCell   *rest;
 
-		foreach(rest, lnext(entry))
+		for_each_cell(rest, lnext(entry))
 		{
 			ColumnDef  *restdef = lfirst(rest);
 
@@ -708,13 +708,13 @@ MergeAttributes(List *schema, List *supers, bool istemp,
 		/*
 		 * Reject duplications in the list of parents.
 		 */
-		if (oidMember(RelationGetRelid(relation), parentOids))
+		if (list_member_oid(parentOids, RelationGetRelid(relation)))
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_TABLE),
 					 errmsg("inherited relation \"%s\" duplicated",
 							parent->relname)));
 
-		parentOids = lappendo(parentOids, RelationGetRelid(relation));
+		parentOids = lappend_oid(parentOids, RelationGetRelid(relation));
 
 		if (relation->rd_rel->relhasoids)
 			parentsWithOids++;
@@ -767,7 +767,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
 				ereport(NOTICE,
 						(errmsg("merging multiple inherited definitions of column \"%s\"",
 								attributeName)));
-				def = (ColumnDef *) nth(exist_attno - 1, inhSchema);
+				def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
 				if (typenameTypeId(def->typename) != attribute->atttypid ||
 					def->typename->typmod != attribute->atttypmod)
 					ereport(ERROR,
@@ -922,7 +922,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
 				ereport(NOTICE,
 						(errmsg("merging column \"%s\" with inherited definition",
 								attributeName)));
-				def = (ColumnDef *) nth(exist_attno - 1, inhSchema);
+				def = (ColumnDef *) list_nth(inhSchema, exist_attno - 1);
 				if (typenameTypeId(def->typename) != typenameTypeId(newdef->typename) ||
 					def->typename->typmod != newdef->typename->typmod)
 					ereport(ERROR,
@@ -1033,7 +1033,7 @@ StoreCatalogInheritance(Oid relationId, List *supers)
 	Relation	relation;
 	TupleDesc	desc;
 	int16		seqNumber;
-	List	   *entry;
+	ListCell   *entry;
 	HeapTuple	tuple;
 
 	/*
@@ -1059,7 +1059,7 @@ StoreCatalogInheritance(Oid relationId, List *supers)
 	seqNumber = 1;
 	foreach(entry, supers)
 	{
-		Oid			parentOid = lfirsto(entry);
+		Oid			parentOid = lfirst_oid(entry);
 		Datum		datum[Natts_pg_inherits];
 		char		nullarr[Natts_pg_inherits];
 		ObjectAddress childobject,
@@ -1113,16 +1113,17 @@ StoreCatalogInheritance(Oid relationId, List *supers)
 static int
 findAttrByName(const char *attributeName, List *schema)
 {
-	List	   *s;
-	int			i = 0;
+	ListCell   *s;
+	int			i = 1;
 
 	foreach(s, schema)
 	{
 		ColumnDef  *def = lfirst(s);
 
-		++i;
 		if (strcmp(attributeName, def->colname) == 0)
 			return i;
+
+		i++;
 	}
 	return 0;
 }
@@ -1198,7 +1199,7 @@ renameatt(Oid myrelid,
 	Form_pg_attribute attform;
 	int			attnum;
 	List	   *indexoidlist;
-	List	   *indexoidscan;
+	ListCell   *indexoidscan;
 
 	/*
 	 * Grab an exclusive lock on the target table, which we will NOT
@@ -1232,8 +1233,8 @@ renameatt(Oid myrelid,
 	 */
 	if (recurse)
 	{
-		List	   *child,
-				   *children;
+		ListCell   *child;
+		List	   *children;
 
 		/* this routine is actually in the planner */
 		children = find_all_inheritors(myrelid);
@@ -1245,7 +1246,7 @@ renameatt(Oid myrelid,
 		 */
 		foreach(child, children)
 		{
-			Oid			childrelid = lfirsto(child);
+			Oid			childrelid = lfirst_oid(child);
 
 			if (childrelid == myrelid)
 				continue;
@@ -1322,7 +1323,7 @@ renameatt(Oid myrelid,
 
 	foreach(indexoidscan, indexoidlist)
 	{
-		Oid			indexoid = lfirsto(indexoidscan);
+		Oid			indexoid = lfirst_oid(indexoidscan);
 		HeapTuple	indextup;
 		Form_pg_index indexform;
 		int			i;
@@ -1370,7 +1371,7 @@ renameatt(Oid myrelid,
 		ReleaseSysCache(indextup);
 	}
 
-	freeList(indexoidlist);
+	list_free(indexoidlist);
 
 	heap_close(attrelation, RowExclusiveLock);
 
@@ -1765,7 +1766,7 @@ static void
 ATController(Relation rel, List *cmds, bool recurse)
 {
 	List	   *wqueue = NIL;
-	List	   *lcmd;
+	ListCell   *lcmd;
 
 	/* Phase 1: preliminary examination of commands, create work queue */
 	foreach(lcmd, cmds)
@@ -1962,7 +1963,7 @@ static void
 ATRewriteCatalogs(List **wqueue)
 {
 	int			pass;
-	List	   *ltab;
+	ListCell   *ltab;
 
 	/*
 	 * We process all the tables "in parallel", one pass at a time.  This
@@ -1979,7 +1980,7 @@ ATRewriteCatalogs(List **wqueue)
 			AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab);
 			List	   *subcmds = tab->subcmds[pass];
 			Relation	rel;
-			List	   *lcmd;
+			ListCell   *lcmd;
 
 			if (subcmds == NIL)
 				continue;
@@ -2107,7 +2108,7 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
 static void
 ATRewriteTables(List **wqueue)
 {
-	List	   *ltab;
+	ListCell   *ltab;
 
 	/* Go through each table that needs to be checked or rewritten */
 	foreach(ltab, *wqueue)
@@ -2215,7 +2216,7 @@ ATRewriteTables(List **wqueue)
 	{
 		AlteredTableInfo  *tab = (AlteredTableInfo *) lfirst(ltab);
 		Relation		rel = NULL;
-		List	   *lcon;
+		ListCell	   *lcon;
 
 		foreach(lcon, tab->constraints)
 		{
@@ -2259,7 +2260,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
 	TupleDesc	newTupDesc;
 	bool		needscan = false;
 	int			i;
-	List	   *l;
+	ListCell   *l;
 	EState	   *estate;
 
 	/*
@@ -2473,7 +2474,7 @@ ATGetQueueEntry(List **wqueue, Relation rel)
 {
 	Oid			relid = RelationGetRelid(rel);
 	AlteredTableInfo *tab;
-	List	   *ltab;
+	ListCell   *ltab;
 
 	foreach(ltab, *wqueue)
 	{
@@ -2554,8 +2555,8 @@ ATSimpleRecursion(List **wqueue, Relation rel,
 	if (recurse && rel->rd_rel->relkind == RELKIND_RELATION)
 	{
 		Oid			relid = RelationGetRelid(rel);
-		List	   *child,
-				   *children;
+		ListCell   *child;
+		List	   *children;
 
 		/* this routine is actually in the planner */
 		children = find_all_inheritors(relid);
@@ -2567,7 +2568,7 @@ ATSimpleRecursion(List **wqueue, Relation rel,
 		 */
 		foreach(child, children)
 		{
-			Oid			childrelid = lfirsto(child);
+			Oid			childrelid = lfirst_oid(child);
 			Relation	childrel;
 
 			if (childrelid == relid)
@@ -2592,15 +2593,15 @@ ATOneLevelRecursion(List **wqueue, Relation rel,
 					AlterTableCmd *cmd)
 {
 	Oid			relid = RelationGetRelid(rel);
-	List	   *child,
-			   *children;
+	ListCell   *child;
+	List	   *children;
 
 	/* this routine is actually in the planner */
 	children = find_inheritance_children(relid);
 
 	foreach(child, children)
 	{
-		Oid			childrelid = lfirsto(child);
+		Oid			childrelid = lfirst_oid(child);
 		Relation	childrel;
 
 		childrel = relation_open(childrelid, AccessExclusiveLock);
@@ -2764,7 +2765,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
 	attribute->atttypmod = colDef->typename->typmod;
 	attribute->attnum = i;
 	attribute->attbyval = tform->typbyval;
-	attribute->attndims = length(colDef->typename->arrayBounds);
+	attribute->attndims = list_length(colDef->typename->arrayBounds);
 	attribute->attstorage = tform->typstorage;
 	attribute->attalign = tform->typalign;
 	attribute->attnotnull = colDef->is_not_null;
@@ -2814,7 +2815,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
 		 * This function is intended for CREATE TABLE, so it processes a
 		 * _list_ of defaults, but we just do one.
 		 */
-		AddRelationRawConstraints(rel, makeList1(rawEnt), NIL);
+		AddRelationRawConstraints(rel, list_make1(rawEnt), NIL);
 
 		/* Make the additional catalog changes visible */
 		CommandCounterIncrement();
@@ -2880,7 +2881,7 @@ ATExecDropNotNull(Relation rel, const char *colName)
 	AttrNumber	attnum;
 	Relation	attr_rel;
 	List	   *indexoidlist;
-	List	   *indexoidscan;
+	ListCell   *indexoidscan;
 
 	/*
 	 * lookup the attribute
@@ -2913,7 +2914,7 @@ ATExecDropNotNull(Relation rel, const char *colName)
 
 	foreach(indexoidscan, indexoidlist)
 	{
-		Oid			indexoid = lfirsto(indexoidscan);
+		Oid			indexoid = lfirst_oid(indexoidscan);
 		HeapTuple	indexTuple;
 		Form_pg_index indexStruct;
 		int			i;
@@ -2945,7 +2946,7 @@ ATExecDropNotNull(Relation rel, const char *colName)
 		ReleaseSysCache(indexTuple);
 	}
 
-	freeList(indexoidlist);
+	list_free(indexoidlist);
 
 	/*
 	 * Okay, actually perform the catalog change ... if needed
@@ -3067,7 +3068,7 @@ ATExecColumnDefault(Relation rel, const char *colName,
 		 * This function is intended for CREATE TABLE, so it processes a
 		 * _list_ of defaults, but we just do one.
 		 */
-		AddRelationRawConstraints(rel, makeList1(rawEnt), NIL);
+		AddRelationRawConstraints(rel, list_make1(rawEnt), NIL);
 	}
 }
 
@@ -3292,12 +3293,12 @@ ATExecDropColumn(Relation rel, const char *colName,
 	if (children)
 	{
 		Relation	attr_rel;
-		List	   *child;
+		ListCell   *child;
 
 		attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock);
 		foreach(child, children)
 		{
-			Oid			childrelid = lfirsto(child);
+			Oid			childrelid = lfirst_oid(child);
 			Relation	childrel;
 			Form_pg_attribute childatt;
 
@@ -3464,14 +3465,14 @@ ATExecAddConstraint(AlteredTableInfo *tab, Relation rel, Node *newConstraint)
 				case CONSTR_CHECK:
 				{
 					List	   *newcons;
-					List	   *lcon;
+					ListCell   *lcon;
 
 					/*
 					 * Call AddRelationRawConstraints to do the work.
 					 * It returns a list of cooked constraints.
 					 */
 					newcons = AddRelationRawConstraints(rel, NIL,
-														makeList1(constr));
+														list_make1(constr));
 					/* Add each constraint to Phase 3's queue */
 					foreach(lcon, newcons)
 					{ 
@@ -3676,7 +3677,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
 		 * get the right answer from the test below on opclass membership
 		 * unless we select the proper operator.)
 		 */
-		Operator	o = oper(makeList1(makeString("=")),
+		Operator	o = oper(list_make1(makeString("=")),
 							 pktypoid[i], fktypoid[i], true);
 
 		if (o == NULL)
@@ -3687,8 +3688,8 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
 							fkconstraint->constr_name),
 					 errdetail("Key columns \"%s\" and \"%s\" "
 							   "are of incompatible types: %s and %s.",
-							   strVal(nth(i, fkconstraint->fk_attrs)),
-							   strVal(nth(i, fkconstraint->pk_attrs)),
+							   strVal(list_nth(fkconstraint->fk_attrs, i)),
+							   strVal(list_nth(fkconstraint->pk_attrs, i)),
 							   format_type_be(fktypoid[i]),
 							   format_type_be(pktypoid[i]))));
 
@@ -3704,8 +3705,8 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
 							fkconstraint->constr_name),
 					 errdetail("Key columns \"%s\" and \"%s\" "
 							   "are of different types: %s and %s.",
-							   strVal(nth(i, fkconstraint->fk_attrs)),
-							   strVal(nth(i, fkconstraint->pk_attrs)),
+							   strVal(list_nth(fkconstraint->fk_attrs, i)),
+							   strVal(list_nth(fkconstraint->pk_attrs, i)),
 							   format_type_be(fktypoid[i]),
 							   format_type_be(pktypoid[i]))));
 
@@ -3774,7 +3775,7 @@ static int
 transformColumnNameList(Oid relId, List *colList,
 						int16 *attnums, Oid *atttypids)
 {
-	List	   *l;
+	ListCell   *l;
 	int			attnum;
 
 	attnum = 0;
@@ -3821,8 +3822,8 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
 						   int16 *attnums, Oid *atttypids,
 						   Oid *opclasses)
 {
-	List	   *indexoidlist,
-			   *indexoidscan;
+	List	   *indexoidlist;
+	ListCell   *indexoidscan;
 	HeapTuple	indexTuple = NULL;
 	Form_pg_index indexStruct = NULL;
 	int			i;
@@ -3836,7 +3837,7 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
 
 	foreach(indexoidscan, indexoidlist)
 	{
-		Oid			indexoid = lfirsto(indexoidscan);
+		Oid			indexoid = lfirst_oid(indexoidscan);
 
 		indexTuple = SearchSysCache(INDEXRELID,
 									ObjectIdGetDatum(indexoid),
@@ -3853,7 +3854,7 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid,
 		indexStruct = NULL;
 	}
 
-	freeList(indexoidlist);
+	list_free(indexoidlist);
 
 	/*
 	 * Check that we found it
@@ -3900,8 +3901,8 @@ transformFkeyCheckAttrs(Relation pkrel,
 {
 	Oid			indexoid = InvalidOid;
 	bool		found = false;
-	List	   *indexoidlist,
-			   *indexoidscan;
+	List	   *indexoidlist;
+	ListCell   *indexoidscan;
 
 	/*
 	 * Get the list of index OIDs for the table from the relcache, and
@@ -3917,7 +3918,7 @@ transformFkeyCheckAttrs(Relation pkrel,
 		int			i,
 					j;
 
-		indexoid = lfirsto(indexoidscan);
+		indexoid = lfirst_oid(indexoidscan);
 		indexTuple = SearchSysCache(INDEXRELID,
 									ObjectIdGetDatum(indexoid),
 									0, 0, 0);
@@ -3982,7 +3983,7 @@ transformFkeyCheckAttrs(Relation pkrel,
 				 errmsg("there is no unique constraint matching given keys for referenced table \"%s\"",
 						RelationGetRelationName(pkrel))));
 
-	freeList(indexoidlist);
+	list_free(indexoidlist);
 
 	return indexoid;
 }
@@ -4001,7 +4002,7 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint,
 	HeapScanDesc scan;
 	HeapTuple	tuple;
 	Trigger		trig;
-	List	   *list;
+	ListCell   *list;
 	int			count;
 
 	/*
@@ -4026,8 +4027,8 @@ validateForeignKeyConstraint(FkConstraint *fkconstraint,
 	trig.tginitdeferred = FALSE;
 
 	trig.tgargs = (char **) palloc(sizeof(char *) *
-								   (4 + length(fkconstraint->fk_attrs)
-									+ length(fkconstraint->pk_attrs)));
+								   (4 + list_length(fkconstraint->fk_attrs)
+									+ list_length(fkconstraint->pk_attrs)));
 
 	trig.tgargs[0] = trig.tgname;
 	trig.tgargs[1] = RelationGetRelationName(rel);
@@ -4094,8 +4095,8 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
 {
 	RangeVar   *myRel;
 	CreateTrigStmt *fk_trigger;
-	List	   *fk_attr;
-	List	   *pk_attr;
+	ListCell   *fk_attr;
+	ListCell   *pk_attr;
 	ObjectAddress trigobj,
 				constrobj;
 
@@ -4146,19 +4147,16 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
 							 makeString(fkconstraint->pktable->relname));
 	fk_trigger->args = lappend(fk_trigger->args,
 			makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
-	fk_attr = fkconstraint->fk_attrs;
-	pk_attr = fkconstraint->pk_attrs;
-	if (length(fk_attr) != length(pk_attr))
+	if (list_length(fkconstraint->fk_attrs) != list_length(fkconstraint->pk_attrs))
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_FOREIGN_KEY),
 				 errmsg("number of referencing and referenced columns for foreign key disagree")));
 
-	while (fk_attr != NIL)
+	forboth(fk_attr, fkconstraint->fk_attrs,
+			pk_attr, fkconstraint->pk_attrs)
 	{
 		fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
 		fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
-		fk_attr = lnext(fk_attr);
-		pk_attr = lnext(pk_attr);
 	}
 
 	trigobj.objectId = CreateTrigger(fk_trigger, true);
@@ -4219,14 +4217,11 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
 							 makeString(fkconstraint->pktable->relname));
 	fk_trigger->args = lappend(fk_trigger->args,
 			makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
-	fk_attr = fkconstraint->fk_attrs;
-	pk_attr = fkconstraint->pk_attrs;
-	while (fk_attr != NIL)
+	forboth(fk_attr, fkconstraint->fk_attrs,
+			pk_attr, fkconstraint->pk_attrs)
 	{
 		fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
 		fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
-		fk_attr = lnext(fk_attr);
-		pk_attr = lnext(pk_attr);
 	}
 
 	trigobj.objectId = CreateTrigger(fk_trigger, true);
@@ -4286,14 +4281,11 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint,
 							 makeString(fkconstraint->pktable->relname));
 	fk_trigger->args = lappend(fk_trigger->args,
 			makeString(fkMatchTypeToString(fkconstraint->fk_matchtype)));
-	fk_attr = fkconstraint->fk_attrs;
-	pk_attr = fkconstraint->pk_attrs;
-	while (fk_attr != NIL)
+	forboth(fk_attr, fkconstraint->fk_attrs,
+			pk_attr, fkconstraint->pk_attrs)
 	{
 		fk_trigger->args = lappend(fk_trigger->args, lfirst(fk_attr));
 		fk_trigger->args = lappend(fk_trigger->args, lfirst(pk_attr));
-		fk_attr = lnext(fk_attr);
-		pk_attr = lnext(pk_attr);
 	}
 
 	trigobj.objectId = CreateTrigger(fk_trigger, true);
@@ -4626,9 +4618,9 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
 				if (relKind == RELKIND_INDEX)
 				{
 					Assert(foundObject.objectSubId == 0);
-					if (!oidMember(foundObject.objectId, tab->changedIndexOids))
+					if (!list_member_oid(tab->changedIndexOids, foundObject.objectId))
 					{
-						tab->changedIndexOids = lappendo(tab->changedIndexOids,
+						tab->changedIndexOids = lappend_oid(tab->changedIndexOids,
 														 foundObject.objectId);
 						tab->changedIndexDefs = lappend(tab->changedIndexDefs,
 														pg_get_indexdef_string(foundObject.objectId));
@@ -4653,9 +4645,9 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
 
 			case OCLASS_CONSTRAINT:
 				Assert(foundObject.objectSubId == 0);
-				if (!oidMember(foundObject.objectId, tab->changedConstraintOids))
+				if (!list_member_oid(tab->changedConstraintOids, foundObject.objectId))
 				{
-					tab->changedConstraintOids = lappendo(tab->changedConstraintOids,
+					tab->changedConstraintOids = lappend_oid(tab->changedConstraintOids,
 														  foundObject.objectId);
 					tab->changedConstraintDefs = lappend(tab->changedConstraintDefs,
 														 pg_get_constraintdef_string(foundObject.objectId));
@@ -4750,7 +4742,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
 	 */
 	attTup->atttypid = targettype;
 	attTup->atttypmod = typename->typmod;
-	attTup->attndims = length(typename->arrayBounds);
+	attTup->attndims = list_length(typename->arrayBounds);
 	attTup->attlen = tform->typlen;
 	attTup->attbyval = tform->typbyval;
 	attTup->attalign = tform->typalign;
@@ -4805,7 +4797,7 @@ static void
 ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab)
 {
 	ObjectAddress obj;
-	List	*l;
+	ListCell	 *l;
 
 	/*
 	 * Re-parse the index and constraint definitions, and attach them to
@@ -4835,7 +4827,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab)
 		obj.classId = get_system_catalog_relid(ConstraintRelationName);
 	foreach(l, tab->changedConstraintOids)
 	{
-		obj.objectId = lfirsto(l);
+		obj.objectId = lfirst_oid(l);
 		obj.objectSubId = 0;
 		performDeletion(&obj, DROP_RESTRICT);
 	}
@@ -4843,7 +4835,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab)
 	obj.classId = RelOid_pg_class;
 	foreach(l, tab->changedIndexOids)
 	{
-		obj.objectId = lfirsto(l);
+		obj.objectId = lfirst_oid(l);
 		obj.objectSubId = 0;
 		performDeletion(&obj, DROP_RESTRICT);
 	}
@@ -4859,7 +4851,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
 {
 	List	   *raw_parsetree_list;
 	List	   *querytree_list;
-	List	   *list_item;
+	ListCell   *list_item;
 
 	/*
 	 * We expect that we only have to do raw parsing and parse analysis, not
@@ -4871,7 +4863,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
 	{
 		Node	   *parsetree = (Node *) lfirst(list_item);
 
-		querytree_list = nconc(querytree_list,
+		querytree_list = list_concat(querytree_list,
 							   parse_analyze(parsetree, NULL, 0));
 	}
 
@@ -4907,7 +4899,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
 			case T_AlterTableStmt:
 			{
 				AlterTableStmt *stmt = (AlterTableStmt *) query->utilityStmt;
-				List	   *lcmd;
+				ListCell	   *lcmd;
 
 				rel = relation_openrv(stmt->relation, AccessExclusiveLock);
 				tab = ATGetQueueEntry(wqueue, rel);
@@ -5002,17 +4994,17 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
 	if (tuple_class->relkind == RELKIND_RELATION ||
 		tuple_class->relkind == RELKIND_TOASTVALUE)
 	{
-		List	   *index_oid_list,
-				   *i;
+		List	   *index_oid_list;
+		ListCell   *i;
 
 		/* Find all the indexes belonging to this relation */
 		index_oid_list = RelationGetIndexList(target_rel);
 
 		/* For each index, recursively change its ownership */
 		foreach(i, index_oid_list)
-			ATExecChangeOwner(lfirsto(i), newOwnerSysId);
+			ATExecChangeOwner(lfirst_oid(i), newOwnerSysId);
 
-		freeList(index_oid_list);
+		list_free(index_oid_list);
 	}
 
 	if (tuple_class->relkind == RELKIND_RELATION)
@@ -5362,7 +5354,7 @@ register_on_commit_action(Oid relid, OnCommitAction action)
 void
 remove_on_commit_action(Oid relid)
 {
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, on_commits)
 	{
@@ -5385,7 +5377,7 @@ remove_on_commit_action(Oid relid)
 void
 PreCommit_on_commit_actions(void)
 {
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, on_commits)
 	{
@@ -5437,40 +5429,34 @@ PreCommit_on_commit_actions(void)
 void
 AtEOXact_on_commit_actions(bool isCommit)
 {
-	List	   *l,
-			   *prev;
+	ListCell *cur_item;
+	ListCell *prev_item;
 
-	prev = NIL;
-	l = on_commits;
-	while (l != NIL)
+	prev_item = NULL;
+	cur_item = list_head(on_commits);
+
+	while (cur_item != NULL)
 	{
-		OnCommitItem *oc = (OnCommitItem *) lfirst(l);
+		OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item);
 
 		if (isCommit ? oc->deleted_in_cur_xact :
 			oc->created_in_cur_xact)
 		{
-			/* This entry must be removed */
-			if (prev != NIL)
-			{
-				lnext(prev) = lnext(l);
-				pfree(l);
-				l = lnext(prev);
-			}
-			else
-			{
-				on_commits = lnext(l);
-				pfree(l);
-				l = on_commits;
-			}
+			/* cur_item must be removed */
+			on_commits = list_delete_cell(on_commits, cur_item, prev_item);
 			pfree(oc);
+			if (prev_item)
+				cur_item = lnext(prev_item);
+			else
+				cur_item = list_head(on_commits);
 		}
 		else
 		{
-			/* This entry must be preserved */
-			oc->created_in_cur_xact = false;
+			/* cur_item must be preserved */
 			oc->deleted_in_cur_xact = false;
-			prev = l;
-			l = lnext(l);
+			oc->created_in_cur_xact = false;
+			prev_item = cur_item;
+			cur_item = lnext(prev_item);
 		}
 	}
 }
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index bddf3f5ad68b7e97c6de952cc21ce4aca587d74d..cfbd58e4282a540528a64d8062bddc5d67c0fdb4 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.164 2004/02/10 01:55:25 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.165 2004/05/26 04:41:12 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -111,19 +111,19 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
 		bool		needconstrrelid = false;
 		void	   *elem = NULL;
 
-		if (strncmp(strVal(llast(stmt->funcname)), "RI_FKey_check_", 14) == 0)
+		if (strncmp(strVal(lfirst(list_tail((stmt->funcname)))), "RI_FKey_check_", 14) == 0)
 		{
 			/* A trigger on FK table. */
 			needconstrrelid = true;
-			if (length(stmt->args) > RI_PK_RELNAME_ARGNO)
-				elem = nth(RI_PK_RELNAME_ARGNO, stmt->args);
+			if (list_length(stmt->args) > RI_PK_RELNAME_ARGNO)
+				elem = list_nth(stmt->args, RI_PK_RELNAME_ARGNO);
 		}
-		else if (strncmp(strVal(llast(stmt->funcname)), "RI_FKey_", 8) == 0)
+		else if (strncmp(strVal(lfirst(list_tail((stmt->funcname)))), "RI_FKey_", 8) == 0)
 		{
 			/* A trigger on PK table. */
 			needconstrrelid = true;
-			if (length(stmt->args) > RI_FK_RELNAME_ARGNO)
-				elem = nth(RI_FK_RELNAME_ARGNO, stmt->args);
+			if (list_length(stmt->args) > RI_FK_RELNAME_ARGNO)
+				elem = list_nth(stmt->args, RI_FK_RELNAME_ARGNO);
 		}
 		if (elem != NULL)
 		{
@@ -318,9 +318,9 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
 
 	if (stmt->args)
 	{
-		List	   *le;
+		ListCell   *le;
 		char	   *args;
-		int16		nargs = length(stmt->args);
+		int16		nargs = list_length(stmt->args);
 		int			len = 0;
 
 		foreach(le, stmt->args)
@@ -1691,7 +1691,7 @@ static bool
 deferredTriggerCheckState(Oid tgoid, int32 itemstate)
 {
 	MemoryContext oldcxt;
-	List	   *sl;
+	ListCell   *sl;
 	DeferredTriggerStatus trigstate;
 
 	/*
@@ -2193,7 +2193,7 @@ DeferredTriggerAbortXact(void)
 void
 DeferredTriggerSetState(ConstraintsSetStmt *stmt)
 {
-	List	   *l;
+	ListCell	   *l;
 
 	/*
 	 * Ignore call if we aren't in a transaction.
@@ -2210,15 +2210,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
 		 * Drop all per-transaction information about individual trigger
 		 * states.
 		 */
-		l = deferredTriggers->deftrig_trigstates;
-		while (l != NIL)
-		{
-			List	   *next = lnext(l);
-
-			pfree(lfirst(l));
-			pfree(l);
-			l = next;
-		}
+		list_free_deep(deferredTriggers->deftrig_trigstates);
 		deferredTriggers->deftrig_trigstates = NIL;
 
 		/*
@@ -2233,7 +2225,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
 		MemoryContext oldcxt;
 		bool		found;
 		DeferredTriggerStatus state;
-		List	   *ls;
+		ListCell   *ls;
 		List	   *loid = NIL;
 
 		/* ----------
@@ -2293,7 +2285,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
 									cname)));
 
 				constr_oid = HeapTupleGetOid(htup);
-				loid = lappendo(loid, constr_oid);
+				loid = lappend_oid(loid, constr_oid);
 				found = true;
 			}
 
@@ -2321,7 +2313,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
 			foreach(ls, deferredTriggers->deftrig_trigstates)
 			{
 				state = (DeferredTriggerStatus) lfirst(ls);
-				if (state->dts_tgoid == lfirsto(l))
+				if (state->dts_tgoid == lfirst_oid(l))
 				{
 					state->dts_tgisdeferred = stmt->deferred;
 					found = true;
@@ -2332,7 +2324,7 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
 			{
 				state = (DeferredTriggerStatus)
 					palloc(sizeof(DeferredTriggerStatusData));
-				state->dts_tgoid = lfirsto(l);
+				state->dts_tgoid = lfirst_oid(l);
 				state->dts_tgisdeferred = stmt->deferred;
 
 				deferredTriggers->deftrig_trigstates =
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 03428369ff485feb00b508b03d2b96e5288ed3e6..d8a2a5b20f5d91c7dfc32d48ae7edc8c80357857 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.56 2004/05/14 16:11:25 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.57 2004/05/26 04:41:12 neilc Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -114,7 +114,7 @@ DefineType(List *names, List *parameters)
 	Oid			sendOid = InvalidOid;
 	Oid			analyzeOid = InvalidOid;
 	char	   *shadow_type;
-	List	   *pl;
+	ListCell   *pl;
 	Oid			typoid;
 	Oid			resulttype;
 
@@ -502,10 +502,10 @@ DefineDomain(CreateDomainStmt *stmt)
 	bool		typNotNull = false;
 	bool		nullDefined = false;
 	Oid			basetypelem;
-	int32		typNDims = length(stmt->typename->arrayBounds);
+	int32		typNDims = list_length(stmt->typename->arrayBounds);
 	HeapTuple	typeTup;
 	List	   *schema = stmt->constraints;
-	List	   *listptr;
+	ListCell   *listptr;
 	Oid			basetypeoid;
 	Oid			domainoid;
 	Form_pg_type baseType;
@@ -1304,7 +1304,7 @@ AlterDomainNotNull(List *names, bool notNull)
 	if (notNull)
 	{
 		List	   *rels;
-		List	   *rt;
+		ListCell   *rt;
 
 		/* Fetch relation list with attributes based on this domain */
 		/* ShareLock is sufficient to prevent concurrent data changes */
@@ -1461,7 +1461,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
 	HeapTuple	tup;
 	Form_pg_type typTup;
 	List	   *rels;
-	List	   *rt;
+	ListCell   *rt;
 	EState	   *estate;
 	ExprContext *econtext;
 	char	   *ccbin;
@@ -1681,7 +1681,7 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
 	{
 		Form_pg_depend pg_depend = (Form_pg_depend) GETSTRUCT(depTup);
 		RelToCheck *rtc = NULL;
-		List	   *rellist;
+		ListCell   *rellist;
 		Form_pg_attribute pg_att;
 		int			ptr;
 
@@ -1848,7 +1848,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
 	/*
 	 * Make sure no outside relations are referred to.
 	 */
-	if (length(pstate->p_rtable) != 0)
+	if (list_length(pstate->p_rtable) != 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
 				 errmsg("cannot use table references in domain check constraint")));
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 476e7e1865e4597899db327b80dae2f870dae9a7..255428fadc7d62491e51c7371d9adb07d18503f2 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.140 2004/05/06 16:59:16 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.141 2004/05/26 04:41:12 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -491,8 +491,8 @@ CreateUser(CreateUserStmt *stmt)
 				sysid_exists = false,
 				havesysid = false;
 	int			max_id;
-	List	   *item,
-			   *option;
+	ListCell   *item;
+	ListCell   *option;
 	char	   *password = NULL;	/* PostgreSQL user password */
 	bool		encrypt_password = Password_encryption; /* encrypt password? */
 	char		encrypted_password[MD5_PASSWD_LEN + 1];
@@ -715,7 +715,7 @@ CreateUser(CreateUserStmt *stmt)
 		ags.name = strVal(lfirst(item));		/* the group name to add
 												 * this in */
 		ags.action = +1;
-		ags.listUsers = makeList1(makeInteger(sysid));
+		ags.listUsers = list_make1(makeInteger(sysid));
 		AlterGroup(&ags, "CREATE USER");
 	}
 
@@ -746,7 +746,7 @@ AlterUser(AlterUserStmt *stmt)
 	TupleDesc	pg_shadow_dsc;
 	HeapTuple	tuple,
 				new_tuple;
-	List	   *option;
+	ListCell   *option;
 	char	   *password = NULL;	/* PostgreSQL user password */
 	bool		encrypt_password = Password_encryption; /* encrypt password? */
 	char		encrypted_password[MD5_PASSWD_LEN + 1];
@@ -1017,7 +1017,7 @@ DropUser(DropUserStmt *stmt)
 {
 	Relation	pg_shadow_rel;
 	TupleDesc	pg_shadow_dsc;
-	List	   *item;
+	ListCell   *item;
 
 	if (!superuser())
 		ereport(ERROR,
@@ -1122,7 +1122,7 @@ DropUser(DropUserStmt *stmt)
 			/* the group name from which to try to drop the user: */
 			ags.name = pstrdup(NameStr(((Form_pg_group) GETSTRUCT(tmp_tuple))->groname));
 			ags.action = -1;
-			ags.listUsers = makeList1(makeInteger(usesysid));
+			ags.listUsers = list_make1(makeInteger(usesysid));
 			AlterGroup(&ags, "DROP USER");
 		}
 		heap_endscan(scan);
@@ -1283,9 +1283,9 @@ CreateGroup(CreateGroupStmt *stmt)
 	int			max_id;
 	Datum		new_record[Natts_pg_group];
 	char		new_record_nulls[Natts_pg_group];
-	List	   *item,
-			   *option,
-			   *newlist = NIL;
+	ListCell   *item;
+	ListCell   *option;
+	List	   *newlist = NIL;
 	IdList	   *grolist;
 	int			sysid = 0;
 	List	   *userElts = NIL;
@@ -1397,8 +1397,8 @@ CreateGroup(CreateGroupStmt *stmt)
 		const char *groupuser = strVal(lfirst(item));
 		int32		userid = get_usesysid(groupuser);
 
-		if (!intMember(userid, newlist))
-			newlist = lappendi(newlist, userid);
+		if (!list_member_int(newlist, userid))
+			newlist = lappend_int(newlist, userid);
 	}
 
 	/* build an array to insert */
@@ -1454,8 +1454,8 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
 	IdList	   *oldarray;
 	Datum		datum;
 	bool		null;
-	List	   *newlist,
-			   *item;
+	List	   *newlist;
+	ListCell   *item;
 
 	/*
 	 * Make sure the user can do this.
@@ -1525,8 +1525,8 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
 				sysid = 0;		/* keep compiler quiet */
 			}
 
-			if (!intMember(sysid, newlist))
-				newlist = lappendi(newlist, sysid);
+			if (!list_member_int(newlist, sysid))
+				newlist = lappend_int(newlist, sysid);
 		}
 
 		/* Do the update */
@@ -1565,8 +1565,8 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
 					/* for dropuser we already know the uid */
 					sysid = intVal(lfirst(item));
 				}
-				if (intMember(sysid, newlist))
-					newlist = lremovei(sysid, newlist);
+				if (list_member_int(newlist, sysid))
+					newlist = list_delete_int(newlist, sysid);
 				else if (!is_dropuser)
 					ereport(WARNING,
 							(errcode(ERRCODE_WARNING),
@@ -1636,9 +1636,9 @@ UpdateGroupMembership(Relation group_rel, HeapTuple group_tuple,
 static IdList *
 IdListToArray(List *members)
 {
-	int			nmembers = length(members);
+	int			nmembers = list_length(members);
 	IdList	   *newarray;
-	List	   *item;
+	ListCell   *item;
 	int			i;
 
 	newarray = palloc(ARR_OVERHEAD(1) + nmembers * sizeof(int32));
@@ -1650,7 +1650,7 @@ IdListToArray(List *members)
 	ARR_DIMS(newarray)[0] = nmembers;	/* axis is this long */
 	i = 0;
 	foreach(item, members)
-		((int *) ARR_DATA_PTR(newarray))[i++] = lfirsti(item);
+		((int *) ARR_DATA_PTR(newarray))[i++] = lfirst_int(item);
 
 	return newarray;
 }
@@ -1679,8 +1679,8 @@ IdArrayToList(IdList *oldarray)
 
 		sysid = ((int32 *) ARR_DATA_PTR(oldarray))[i];
 		/* filter out any duplicates --- probably a waste of time */
-		if (!intMember(sysid, newlist))
-			newlist = lappendi(newlist, sysid);
+		if (!list_member_int(newlist, sysid))
+			newlist = lappend_int(newlist, sysid);
 	}
 
 	return newlist;
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 5822b7f210cbc42ea2d88d70f00594e3884c6ed2..b2ebda8e975b4af405c732ac30a3c8c44bc57e26 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.277 2004/05/22 23:14:38 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.278 2004/05/26 04:41:12 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -164,8 +164,8 @@ vacuum(VacuumStmt *vacstmt)
 	bool		all_rels,
 				in_outer_xact,
 				use_own_xacts;
-	List	   *relations,
-			   *cur;
+	List	   *relations;
+	ListCell   *cur;
 
 	if (vacstmt->verbose)
 		elevel = INFO;
@@ -276,7 +276,7 @@ vacuum(VacuumStmt *vacstmt)
 		Assert(vacstmt->analyze);
 		if (in_outer_xact)
 			use_own_xacts = false;
-		else if (length(relations) > 1)
+		else if (list_length(relations) > 1)
 			use_own_xacts = true;
 		else
 			use_own_xacts = false;
@@ -312,7 +312,7 @@ vacuum(VacuumStmt *vacstmt)
 	 */
 	foreach(cur, relations)
 	{
-		Oid			relid = lfirsto(cur);
+		Oid			relid = lfirst_oid(cur);
 
 		if (vacstmt->vacuum)
 		{
@@ -431,7 +431,7 @@ get_rel_oids(const RangeVar *vacrel, const char *stmttype)
 
 		/* Make a relation list entry for this guy */
 		oldcontext = MemoryContextSwitchTo(vac_context);
-		oid_list = lappendo(oid_list, relid);
+		oid_list = lappend_oid(oid_list, relid);
 		MemoryContextSwitchTo(oldcontext);
 	}
 	else
@@ -455,7 +455,7 @@ get_rel_oids(const RangeVar *vacrel, const char *stmttype)
 		{
 			/* Make a relation list entry for this guy */
 			oldcontext = MemoryContextSwitchTo(vac_context);
-			oid_list = lappendo(oid_list, HeapTupleGetOid(tuple));
+			oid_list = lappend_oid(oid_list, HeapTupleGetOid(tuple));
 			MemoryContextSwitchTo(oldcontext);
 		}
 
@@ -3061,13 +3061,13 @@ vac_cmp_vtlinks(const void *left, const void *right)
 void
 vac_open_indexes(Relation relation, int *nindexes, Relation **Irel)
 {
-	List	   *indexoidlist,
-			   *indexoidscan;
+	List	   *indexoidlist;
+	ListCell   *indexoidscan;
 	int			i;
 
 	indexoidlist = RelationGetIndexList(relation);
 
-	*nindexes = length(indexoidlist);
+	*nindexes = list_length(indexoidlist);
 
 	if (*nindexes > 0)
 		*Irel = (Relation *) palloc(*nindexes * sizeof(Relation));
@@ -3077,13 +3077,13 @@ vac_open_indexes(Relation relation, int *nindexes, Relation **Irel)
 	i = 0;
 	foreach(indexoidscan, indexoidlist)
 	{
-		Oid			indexoid = lfirsto(indexoidscan);
+		Oid			indexoid = lfirst_oid(indexoidscan);
 
 		(*Irel)[i] = index_open(indexoid);
 		i++;
 	}
 
-	freeList(indexoidlist);
+	list_free(indexoidlist);
 }
 
 
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 58cf97408f3193c46338029c780488a5191d8ef7..4a58419079ada18a80ce980b416e6e072ad4c4d9 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.96 2004/05/23 23:12:11 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.97 2004/05/26 04:41:13 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -48,7 +48,7 @@ assign_datestyle(const char *value, bool doit, GucSource source)
 	char	   *rawstring;
 	char	   *result;
 	List	   *elemlist;
-	List	   *l;
+	ListCell   *l;
 
 	/* Need a modifiable copy of string */
 	rawstring = pstrdup(value);
@@ -58,7 +58,7 @@ assign_datestyle(const char *value, bool doit, GucSource source)
 	{
 		/* syntax error in list */
 		pfree(rawstring);
-		freeList(elemlist);
+		list_free(elemlist);
 		if (source >= PGC_S_INTERACTIVE)
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -159,7 +159,7 @@ assign_datestyle(const char *value, bool doit, GucSource source)
 		ok = false;
 
 	pfree(rawstring);
-	freeList(elemlist);
+	list_free(elemlist);
 
 	if (!ok)
 	{
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index a8c3cb5ce07ca2d220c0c8c2f295928d4bb2381e..4c27bd67199113ab98da4576010f54b6241eea88 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.81 2004/01/14 23:01:54 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.82 2004/05/26 04:41:13 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,8 +47,8 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
 	Oid			viewOid,
 				namespaceId;
 	CreateStmt *createStmt = makeNode(CreateStmt);
-	List	   *attrList,
-			   *t;
+	List	   *attrList;
+	ListCell   *t;
 
 	/*
 	 * create a list of ColumnDef nodes based on the names and types of
@@ -217,7 +217,7 @@ FormViewRetrieveRule(const RangeVar *view, Query *viewParse, bool replace)
 	rule->whereClause = NULL;
 	rule->event = CMD_SELECT;
 	rule->instead = true;
-	rule->actions = makeList1(viewParse);
+	rule->actions = list_make1(viewParse);
 	rule->replace = replace;
 
 	return rule;
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c
index 8bbd1942eba02fa7a0c7c51be0a02501c28a651c..fdf55b31c0c88120ce4078689b59bb0f52e66beb 100644
--- a/src/backend/executor/execAmi.c
+++ b/src/backend/executor/execAmi.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.78 2004/03/02 18:56:15 tgl Exp $
+ *	$PostgreSQL: pgsql/src/backend/executor/execAmi.c,v 1.79 2004/05/26 04:41:14 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -64,11 +64,11 @@ ExecReScan(PlanState *node, ExprContext *exprCtxt)
 	/* If we have changed parameters, propagate that info */
 	if (node->chgParam != NULL)
 	{
-		List	   *lst;
+		ListCell	*l;
 
-		foreach(lst, node->initPlan)
+		foreach(l, node->initPlan)
 		{
-			SubPlanState *sstate = (SubPlanState *) lfirst(lst);
+			SubPlanState *sstate = (SubPlanState *) lfirst(l);
 			PlanState  *splan = sstate->planstate;
 
 			if (splan->plan->extParam != NULL)	/* don't care about child
@@ -77,9 +77,9 @@ ExecReScan(PlanState *node, ExprContext *exprCtxt)
 			if (splan->chgParam != NULL)
 				ExecReScanSetParamPlan(sstate, node);
 		}
-		foreach(lst, node->subPlan)
+		foreach(l, node->subPlan)
 		{
-			SubPlanState *sstate = (SubPlanState *) lfirst(lst);
+			SubPlanState *sstate = (SubPlanState *) lfirst(l);
 			PlanState  *splan = sstate->planstate;
 
 			if (splan->plan->extParam != NULL)
@@ -315,7 +315,7 @@ ExecSupportsBackwardScan(Plan *node)
 
 		case T_Append:
 			{
-				List	   *l;
+				ListCell   *l;
 
 				foreach(l, ((Append *) node)->appendplans)
 				{
diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c
index 0411e2e553d57fb6576cb84bf15de4afef8105c8..20c385134b272d95ec8c3afb91c2d1e8d6cef512 100644
--- a/src/backend/executor/execJunk.c
+++ b/src/backend/executor/execJunk.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/execJunk.c,v 1.39 2004/04/07 18:46:12 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/execJunk.c,v 1.40 2004/05/26 04:41:14 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -68,7 +68,7 @@ ExecInitJunkFilter(List *targetList, TupleDesc tupType,
 	int			len,
 				cleanLength;
 	TupleDesc	cleanTupType;
-	List	   *t;
+	ListCell   *t;
 	TargetEntry *tle;
 	Resdom	   *resdom,
 			   *cleanResdom;
@@ -184,7 +184,7 @@ ExecGetJunkAttribute(JunkFilter *junkfilter,
 					 bool *isNull)
 {
 	List	   *targetList;
-	List	   *t;
+	ListCell   *t;
 	AttrNumber	resno;
 	TupleDesc	tupType;
 	HeapTuple	tuple;
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index e8ed4ce5cc46f702a438610d2332d659eb15dc73..5ee954ab4d68593474e997efe6a16a6e43920898 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.231 2004/05/11 17:36:12 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.232 2004/05/26 04:41:14 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -353,11 +353,11 @@ ExecutorRewind(QueryDesc *queryDesc)
 void
 ExecCheckRTPerms(List *rangeTable)
 {
-	List	   *lp;
+	ListCell   *l;
 
-	foreach(lp, rangeTable)
+	foreach(l, rangeTable)
 	{
-		RangeTblEntry *rte = lfirst(lp);
+		RangeTblEntry *rte = lfirst(l);
 
 		ExecCheckRTEPerms(rte);
 	}
@@ -427,7 +427,7 @@ ExecCheckRTEPerms(RangeTblEntry *rte)
 static void
 ExecCheckXactReadOnly(Query *parsetree)
 {
-	List	   *lp;
+	ListCell   *l;
 
 	/*
 	 * CREATE TABLE AS or SELECT INTO?
@@ -438,9 +438,9 @@ ExecCheckXactReadOnly(Query *parsetree)
 		goto fail;
 
 	/* Fail if write permissions are requested on any non-temp table */
-	foreach(lp, parsetree->rtable)
+	foreach(l, parsetree->rtable)
 	{
-		RangeTblEntry *rte = lfirst(lp);
+		RangeTblEntry *rte = lfirst(l);
 
 		if (rte->rtekind == RTE_SUBQUERY)
 		{
@@ -521,20 +521,20 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
 			 * Multiple result relations (due to inheritance)
 			 * parseTree->resultRelations identifies them all
 			 */
-			ResultRelInfo *resultRelInfo;
+			ResultRelInfo	*resultRelInfo;
+			ListCell		*l;
 
 			numResultRelations = length(resultRelations);
 			resultRelInfos = (ResultRelInfo *)
 				palloc(numResultRelations * sizeof(ResultRelInfo));
 			resultRelInfo = resultRelInfos;
-			while (resultRelations != NIL)
+			foreach(l, resultRelations)
 			{
 				initResultRelInfo(resultRelInfo,
-								  lfirsti(resultRelations),
+								  lfirst_int(l),
 								  rangeTable,
 								  operation);
 				resultRelInfo++;
-				resultRelations = lnext(resultRelations);
 			}
 		}
 		else
@@ -586,7 +586,7 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
 	estate->es_rowMark = NIL;
 	if (parseTree->rowMarks != NIL)
 	{
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, parseTree->rowMarks)
 		{
@@ -651,7 +651,7 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
 	 */
 	{
 		bool		junk_filter_needed = false;
-		List	   *tlist;
+		ListCell   *tlist;
 
 		switch (operation)
 		{
@@ -950,7 +950,7 @@ ExecEndPlan(PlanState *planstate, EState *estate)
 {
 	ResultRelInfo *resultRelInfo;
 	int			i;
-	List	   *l;
+	ListCell   *l;
 
 	/*
 	 * shut down any PlanQual processing we were doing
@@ -1132,7 +1132,7 @@ lnext:	;
 			}
 			else if (estate->es_rowMark != NIL)
 			{
-				List	   *l;
+				ListCell   *l;
 
 		lmark:	;
 				foreach(l, estate->es_rowMark)
@@ -1785,7 +1785,7 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
 		relation = estate->es_result_relation_info->ri_RelationDesc;
 	else
 	{
-		List	   *l;
+		ListCell   *l;
 
 		relation = NULL;
 		foreach(l, estate->es_rowMark)
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index 4a50c4bc9096c2cb6fbcd450f23adf0396cde760..dbe1b9b9fd692d91e45b03218e2fccd367e36ae4 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/execProcnode.c,v 1.42 2004/03/02 22:17:34 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/execProcnode.c,v 1.43 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -119,7 +119,7 @@ ExecInitNode(Plan *node, EState *estate)
 {
 	PlanState  *result;
 	List	   *subps;
-	List	   *subp;
+	ListCell   *l;
 
 	/*
 	 * do nothing when we get to the end of a leaf on tree.
@@ -224,9 +224,9 @@ ExecInitNode(Plan *node, EState *estate)
 	 * them in a separate list for us.
 	 */
 	subps = NIL;
-	foreach(subp, node->initPlan)
+	foreach(l, node->initPlan)
 	{
-		SubPlan    *subplan = (SubPlan *) lfirst(subp);
+		SubPlan    *subplan = (SubPlan *) lfirst(l);
 		SubPlanState *sstate;
 
 		Assert(IsA(subplan, SubPlan));
@@ -242,9 +242,9 @@ ExecInitNode(Plan *node, EState *estate)
 	 * do this after initializing initPlans, in case their arguments
 	 * contain subPlans (is that actually possible? perhaps not).
 	 */
-	foreach(subp, result->subPlan)
+	foreach(l, result->subPlan)
 	{
-		SubPlanState *sstate = (SubPlanState *) lfirst(subp);
+		SubPlanState *sstate = (SubPlanState *) lfirst(l);
 
 		Assert(IsA(sstate, SubPlanState));
 		ExecInitSubPlan(sstate, estate);
@@ -483,7 +483,7 @@ ExecCountSlotsNode(Plan *node)
 void
 ExecEndNode(PlanState *node)
 {
-	List	   *subp;
+	ListCell   *subp;
 
 	/*
 	 * do nothing when we get to the end of a leaf on tree.
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index d44f580be024486d921c42476f75d873d1fc3945..9308848964717a893a315257043d335e0817052a 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.159 2004/05/10 22:44:43 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.160 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -217,7 +217,7 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
 	ArrayType  *array_source;
 	ArrayType  *resultArray;
 	bool		isAssignment = (arrayRef->refassgnexpr != NULL);
-	List	   *elt;
+	ListCell   *l;
 	int			i = 0,
 				j = 0;
 	IntArray	upper,
@@ -258,9 +258,9 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
 		array_source = NULL;
 	}
 
-	foreach(elt, astate->refupperindexpr)
+	foreach(l, astate->refupperindexpr)
 	{
-		ExprState  *eltstate = (ExprState *) lfirst(elt);
+		ExprState  *eltstate = (ExprState *) lfirst(l);
 
 		if (i >= MAXDIM)
 			ereport(ERROR,
@@ -284,9 +284,9 @@ ExecEvalArrayRef(ArrayRefExprState *astate,
 
 	if (astate->reflowerindexpr != NIL)
 	{
-		foreach(elt, astate->reflowerindexpr)
+		foreach(l, astate->reflowerindexpr)
 		{
-			ExprState  *eltstate = (ExprState *) lfirst(elt);
+			ExprState  *eltstate = (ExprState *) lfirst(l);
 
 			if (j >= MAXDIM)
 				ereport(ERROR,
@@ -798,7 +798,7 @@ ExecEvalFuncArgs(FunctionCallInfo fcinfo,
 {
 	ExprDoneCond argIsDone;
 	int			i;
-	List	   *arg;
+	ListCell   *arg;
 
 	argIsDone = ExprSingleResult;		/* default assumption */
 
@@ -1070,7 +1070,7 @@ ExecMakeFunctionResultNoSets(FuncExprState *fcache,
 							 bool *isNull,
 							 ExprDoneCond *isDone)
 {
-	List	   *arg;
+	ListCell   *arg;
 	Datum		result;
 	FunctionCallInfoData fcinfo;
 	int			i;
@@ -1703,7 +1703,7 @@ static Datum
 ExecEvalNot(BoolExprState *notclause, ExprContext *econtext,
 			bool *isNull, ExprDoneCond *isDone)
 {
-	ExprState  *clause = lfirst(notclause->args);
+	ExprState  *clause = linitial(notclause->args);
 	Datum		expr_value;
 
 	if (isDone)
@@ -1734,7 +1734,7 @@ ExecEvalOr(BoolExprState *orExpr, ExprContext *econtext,
 		   bool *isNull, ExprDoneCond *isDone)
 {
 	List	   *clauses = orExpr->args;
-	List	   *clause;
+	ListCell   *clause;
 	bool		AnyNull;
 
 	if (isDone)
@@ -1786,7 +1786,7 @@ ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
 			bool *isNull, ExprDoneCond *isDone)
 {
 	List	   *clauses = andExpr->args;
-	List	   *clause;
+	ListCell   *clause;
 	bool		AnyNull;
 
 	if (isDone)
@@ -1802,6 +1802,7 @@ ExecEvalAnd(BoolExprState *andExpr, ExprContext *econtext,
 	 * when you interpret NULL as "don't know", using the same sort of
 	 * reasoning as for OR, above.
 	 */
+
 	foreach(clause, clauses)
 	{
 		ExprState  *clausestate = (ExprState *) lfirst(clause);
@@ -1838,7 +1839,7 @@ ExecEvalCase(CaseExprState *caseExpr, ExprContext *econtext,
 			 bool *isNull, ExprDoneCond *isDone)
 {
 	List	   *clauses = caseExpr->args;
-	List	   *clause;
+	ListCell   *clause;
 	Datum		save_datum;
 	bool		save_isNull;
 
@@ -1938,7 +1939,7 @@ ExecEvalArray(ArrayExprState *astate, ExprContext *econtext,
 {
 	ArrayExpr  *arrayExpr = (ArrayExpr *) astate->xprstate.expr;
 	ArrayType  *result;
-	List	   *element;
+	ListCell   *element;
 	Oid			element_type = arrayExpr->element_typeid;
 	int			ndims = 0;
 	int			dims[MAXDIM];
@@ -2118,7 +2119,7 @@ ExecEvalRow(RowExprState *rstate,
 	Datum	   *values;
 	char	   *nulls;
 	int			nargs;
-	List	   *arg;
+	ListCell   *arg;
 	int			i;
 
 	/* Set default values for result flags: non-null, not a set result */
@@ -2161,7 +2162,7 @@ static Datum
 ExecEvalCoalesce(CoalesceExprState *coalesceExpr, ExprContext *econtext,
 				 bool *isNull, ExprDoneCond *isDone)
 {
-	List	   *arg;
+	ListCell   *arg;
 
 	if (isDone)
 		*isDone = ExprSingleResult;
@@ -2390,7 +2391,7 @@ ExecEvalCoerceToDomain(CoerceToDomainState *cstate, ExprContext *econtext,
 {
 	CoerceToDomain *ctest = (CoerceToDomain *) cstate->xprstate.expr;
 	Datum		result;
-	List	   *l;
+	ListCell   *l;
 
 	result = ExecEvalExpr(cstate->arg, econtext, isNull, isDone);
 
@@ -2826,14 +2827,14 @@ ExecInitExpr(Expr *node, PlanState *parent)
 				CaseExpr   *caseexpr = (CaseExpr *) node;
 				CaseExprState *cstate = makeNode(CaseExprState);
 				FastList	outlist;
-				List	   *inlist;
+				ListCell   *l;
 
 				cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCase;
 				cstate->arg = ExecInitExpr(caseexpr->arg, parent);
 				FastListInit(&outlist);
-				foreach(inlist, caseexpr->args)
+				foreach(l, caseexpr->args)
 				{
-					CaseWhen   *when = (CaseWhen *) lfirst(inlist);
+					CaseWhen   *when = (CaseWhen *) lfirst(l);
 					CaseWhenState *wstate = makeNode(CaseWhenState);
 
 					Assert(IsA(when, CaseWhen));
@@ -2853,13 +2854,13 @@ ExecInitExpr(Expr *node, PlanState *parent)
 				ArrayExpr  *arrayexpr = (ArrayExpr *) node;
 				ArrayExprState *astate = makeNode(ArrayExprState);
 				FastList	outlist;
-				List	   *inlist;
+				ListCell   *l;
 
 				astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalArray;
 				FastListInit(&outlist);
-				foreach(inlist, arrayexpr->elements)
+				foreach(l, arrayexpr->elements)
 				{
-					Expr	   *e = (Expr *) lfirst(inlist);
+					Expr	   *e = (Expr *) lfirst(l);
 					ExprState  *estate;
 
 					estate = ExecInitExpr(e, parent);
@@ -2879,13 +2880,13 @@ ExecInitExpr(Expr *node, PlanState *parent)
 				RowExpr	   *rowexpr = (RowExpr *) node;
 				RowExprState *rstate = makeNode(RowExprState);
 				List	   *outlist;
-				List	   *inlist;
+				ListCell   *l;
 
 				rstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalRow;
 				outlist = NIL;
-				foreach(inlist, rowexpr->args)
+				foreach(l, rowexpr->args)
 				{
-					Expr	   *e = (Expr *) lfirst(inlist);
+					Expr	   *e = (Expr *) lfirst(l);
 					ExprState  *estate;
 
 					estate = ExecInitExpr(e, parent);
@@ -2912,13 +2913,13 @@ ExecInitExpr(Expr *node, PlanState *parent)
 				CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
 				CoalesceExprState *cstate = makeNode(CoalesceExprState);
 				FastList	outlist;
-				List	   *inlist;
+				ListCell   *l;
 
 				cstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalCoalesce;
 				FastListInit(&outlist);
-				foreach(inlist, coalesceexpr->args)
+				foreach(l, coalesceexpr->args)
 				{
-					Expr	   *e = (Expr *) lfirst(inlist);
+					Expr	   *e = (Expr *) lfirst(l);
 					ExprState  *estate;
 
 					estate = ExecInitExpr(e, parent);
@@ -2984,13 +2985,13 @@ ExecInitExpr(Expr *node, PlanState *parent)
 		case T_List:
 			{
 				FastList	outlist;
-				List	   *inlist;
+				ListCell   *l;
 
 				FastListInit(&outlist);
-				foreach(inlist, (List *) node)
+				foreach(l, (List *) node)
 				{
 					FastAppend(&outlist,
-							   ExecInitExpr((Expr *) lfirst(inlist),
+							   ExecInitExpr((Expr *) lfirst(l),
 											parent));
 				}
 				/* Don't fall through to the "common" code below */
@@ -3101,7 +3102,7 @@ ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
 {
 	bool		result;
 	MemoryContext oldContext;
-	List	   *qlist;
+	ListCell   *l;
 
 	/*
 	 * debugging stuff
@@ -3131,9 +3132,9 @@ ExecQual(List *qual, ExprContext *econtext, bool resultForNull)
 	 */
 	result = true;
 
-	foreach(qlist, qual)
+	foreach(l, qual)
 	{
-		ExprState  *clause = (ExprState *) lfirst(qlist);
+		ExprState  *clause = (ExprState *) lfirst(l);
 		Datum		expr_value;
 		bool		isNull;
 
@@ -3179,7 +3180,7 @@ int
 ExecCleanTargetListLength(List *targetlist)
 {
 	int			len = 0;
-	List	   *tl;
+	ListCell   *tl;
 
 	foreach(tl, targetlist)
 	{
@@ -3219,7 +3220,7 @@ ExecTargetList(List *targetlist,
 			   ExprDoneCond *isDone)
 {
 	MemoryContext oldContext;
-	List	   *tl;
+	ListCell   *tl;
 	bool		isNull;
 	bool		haveDoneSets;
 
diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c
index 2508a9f2b1b26e705a85cc1f5870fbeaee9d5e0e..9564dd16740f7af6582b1b97228e53bcd476e5d6 100644
--- a/src/backend/executor/execScan.c
+++ b/src/backend/executor/execScan.c
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/execScan.c,v 1.30 2004/01/22 02:23:21 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/execScan.c,v 1.31 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -195,6 +195,7 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc
 	int			numattrs = tupdesc->natts;
 	int			attrno;
 	bool		hasoid;
+	ListCell   *tlist_item = list_head(tlist);
 
 	/* Check the tlist attributes */
 	for (attrno = 1; attrno <= numattrs; attrno++)
@@ -202,9 +203,9 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc
 		Form_pg_attribute att_tup = tupdesc->attrs[attrno - 1];
 		Var		   *var;
 
-		if (tlist == NIL)
+		if (tlist_item == NULL)
 			return false;		/* tlist too short */
-		var = (Var *) ((TargetEntry *) lfirst(tlist))->expr;
+		var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
 		if (!var || !IsA(var, Var))
 			return false;		/* tlist item not a Var */
 		Assert(var->varno == varno);
@@ -216,10 +217,10 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc
 		Assert(var->vartype == att_tup->atttypid);
 		Assert(var->vartypmod == att_tup->atttypmod);
 
-		tlist = lnext(tlist);
+		tlist_item = lnext(tlist_item);
 	}
 
-	if (tlist)
+	if (tlist_item)
 		return false;			/* tlist too long */
 
 	/*
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 725b8fea0ffcc9cacc3bae759ff6c260bf69b389..a28735c0f1eb73777a99e31e522f5fdf8acc20ad 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.77 2004/05/10 22:44:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.78 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -569,7 +569,7 @@ static TupleDesc
 ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
 {
 	TupleDesc	 typeInfo;
-	List		*l;
+	ListCell	*l;
 	int			 len;
 	int			 cur_resno = 1;
 
@@ -606,7 +606,7 @@ TupleDesc
 ExecTypeFromExprList(List *exprList)
 {
 	TupleDesc	 typeInfo;
-	List		*l;
+	ListCell	*l;
 	int			 cur_resno = 1;
 	char		fldname[NAMEDATALEN];
 
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 9702b1cf0aa7dc2cca0d4bdc984a974207ef74fc..811ec513e03eef80d72c4444d0e1709918d61377 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.110 2004/03/17 20:48:42 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.111 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -248,7 +248,10 @@ FreeExecutorState(EState *estate)
 	 */
 	while (estate->es_exprcontexts)
 	{
-		FreeExprContext((ExprContext *) lfirst(estate->es_exprcontexts));
+		/* XXX: seems there ought to be a faster way to implement this
+		 * than repeated lremove(), no?
+		 */
+		FreeExprContext((ExprContext *) linitial(estate->es_exprcontexts));
 		/* FreeExprContext removed the list link for us */
 	}
 
@@ -636,8 +639,8 @@ void
 ExecOpenIndices(ResultRelInfo *resultRelInfo)
 {
 	Relation	resultRelation = resultRelInfo->ri_RelationDesc;
-	List	   *indexoidlist,
-			   *indexoidscan;
+	List	   *indexoidlist;
+	ListCell   *l;
 	int			len,
 				i;
 	RelationPtr relationDescs;
@@ -671,9 +674,9 @@ ExecOpenIndices(ResultRelInfo *resultRelInfo)
 	 * For each index, open the index relation and save pg_index info.
 	 */
 	i = 0;
-	foreach(indexoidscan, indexoidlist)
+	foreach(l, indexoidlist)
 	{
-		Oid			indexOid = lfirsto(indexoidscan);
+		Oid			indexOid = lfirsto(l);
 		Relation	indexDesc;
 		IndexInfo  *ii;
 
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index c07eac5faf6d8bd4c09051f135060e68235c33ce..2e75813a2ab97873c8788f963db097dcce6a4e86 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.80 2004/04/02 23:14:08 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.81 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -92,7 +92,7 @@ init_execution_state(List *queryTree_list)
 {
 	execution_state *firstes = NULL;
 	execution_state *preves = NULL;
-	List	   *qtl_item;
+	ListCell	    *qtl_item;
 
 	foreach(qtl_item, queryTree_list)
 	{
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 0a872221276b4da83ef5e1b874e633da9c1beb54..9884cfecd38637e1503e3e956b317c58e1c5560f 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -45,7 +45,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.119 2004/03/13 00:54:10 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.120 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1033,7 +1033,7 @@ ExecInitAgg(Agg *node, EState *estate)
 	ExprContext *econtext;
 	int			numaggs,
 				aggno;
-	List	   *alist;
+	ListCell   *l;
 
 	/*
 	 * create state structure
@@ -1187,9 +1187,9 @@ ExecInitAgg(Agg *node, EState *estate)
 	 * result entry by giving them duplicate aggno values.
 	 */
 	aggno = -1;
-	foreach(alist, aggstate->aggs)
+	foreach(l, aggstate->aggs)
 	{
-		AggrefExprState *aggrefstate = (AggrefExprState *) lfirst(alist);
+		AggrefExprState *aggrefstate = (AggrefExprState *) lfirst(l);
 		Aggref	   *aggref = (Aggref *) aggrefstate->xprstate.expr;
 		AggStatePerAgg peraggstate;
 		Oid			inputType;
diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c
index c0d74c47784d072469881445c40e006f99ea17b9..f23554e0bc8c82512d5cd880e08d9a6efbc3559f 100644
--- a/src/backend/executor/nodeAppend.c
+++ b/src/backend/executor/nodeAppend.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeAppend.c,v 1.56 2004/01/22 02:23:21 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeAppend.c,v 1.57 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -237,7 +237,7 @@ ExecInitAppend(Append *node, EState *estate)
 int
 ExecCountSlotsAppend(Append *node)
 {
-	List	   *plan;
+	ListCell   *plan;
 	int			nSlots = 0;
 
 	foreach(plan, node->appendplans)
diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c
index 7847b24ffe20f2e316e847cf2fefe1a36c4ad6f7..55aa120ec9b46f7a4acbc02ee3e54fc71105b6f0 100644
--- a/src/backend/executor/nodeFunctionscan.c
+++ b/src/backend/executor/nodeFunctionscan.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.24 2004/04/01 21:28:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeFunctionscan.c,v 1.25 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -201,7 +201,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate)
 	else if (functyptype == 'b' || functyptype == 'd')
 	{
 		/* Must be a base data type, i.e. scalar */
-		char	   *attname = strVal(lfirst(rte->eref->colnames));
+		char	   *attname = strVal(linitial(rte->eref->colnames));
 
 		tupdesc = CreateTemplateTupleDesc(1, false);
 		TupleDescInitEntry(tupdesc,
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index a6a386f97f628f1ccd1225bd84892faf2e1066f6..bf9ed89e9491a0a9199bd3ed73b11ce6295f0f76 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.83 2004/03/17 01:02:23 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.84 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -202,7 +202,7 @@ ExecHashTableCreate(Hash *node, List *hashOperators)
 	int			nbatch;
 	int			nkeys;
 	int			i;
-	List	   *ho;
+	ListCell   *ho;
 	MemoryContext oldcxt;
 
 	/*
@@ -518,7 +518,7 @@ ExecHashGetBucket(HashJoinTable hashtable,
 {
 	uint32		hashkey = 0;
 	int			bucketno;
-	List	   *hk;
+	ListCell   *hk;
 	int			i = 0;
 	MemoryContext oldContext;
 
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index f0c1ee69e69bf8063142b9f98f683cfa9dd18e7c..da2f6cdac8c9680032f2f560e75a6fae68d7b612 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.60 2004/01/07 18:56:26 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeHashjoin.c,v 1.61 2004/05/26 04:41:15 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -311,7 +311,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate)
 	List	   *lclauses;
 	List	   *rclauses;
 	List	   *hoperators;
-	List	   *hcl;
+	ListCell   *l;
 
 	/*
 	 * create state structure
@@ -419,15 +419,15 @@ ExecInitHashJoin(HashJoin *node, EState *estate)
 	lclauses = NIL;
 	rclauses = NIL;
 	hoperators = NIL;
-	foreach(hcl, hjstate->hashclauses)
+	foreach(l, hjstate->hashclauses)
 	{
-		FuncExprState *fstate = (FuncExprState *) lfirst(hcl);
+		FuncExprState *fstate = (FuncExprState *) lfirst(l);
 		OpExpr	   *hclause;
 
 		Assert(IsA(fstate, FuncExprState));
 		hclause = (OpExpr *) fstate->xprstate.expr;
 		Assert(IsA(hclause, OpExpr));
-		lclauses = lappend(lclauses, lfirst(fstate->args));
+		lclauses = lappend(lclauses, linitial(fstate->args));
 		rclauses = lappend(rclauses, lsecond(fstate->args));
 		hoperators = lappendo(hoperators, hclause->opno);
 	}
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index a68dbf1dca975ea10efa3ffbe49cb9b1746f994a..c306e4563b94419a4f1058b589aebe6fd35d89a2 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.93 2004/04/21 18:24:26 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.94 2004/05/26 04:41:16 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -146,7 +146,7 @@ IndexNext(IndexScanState *node)
 	if (estate->es_evTuple != NULL &&
 		estate->es_evTuple[scanrelid - 1] != NULL)
 	{
-		List	   *qual;
+		ListCell   *qual;
 
 		if (estate->es_evTupleNull[scanrelid - 1])
 			return slot;		/* return empty slot */
@@ -164,7 +164,7 @@ IndexNext(IndexScanState *node)
 			if (ExecQual((List *) lfirst(qual), econtext, false))
 				break;
 		}
-		if (qual == NIL)		/* would not be returned by indices */
+		if (qual == NULL)		/* would not be returned by indices */
 			slot->val = NULL;
 
 		/* Flag for the next call that no more tuples */
@@ -283,11 +283,11 @@ IndexNext(IndexScanState *node)
 				{
 					bool		prev_matches = false;
 					int			prev_index;
-					List	   *qual;
+					ListCell   *qual;
 
 					econtext->ecxt_scantuple = slot;
 					ResetExprContext(econtext);
-					qual = node->indxqualorig;
+					qual = list_head(node->indxqualorig);
 					for (prev_index = 0;
 						 prev_index < node->iss_IndexPtr;
 						 prev_index++)
@@ -641,11 +641,11 @@ IndexScanState *
 ExecInitIndexScan(IndexScan *node, EState *estate)
 {
 	IndexScanState *indexstate;
-	List	   *indxqual;
-	List	   *indxstrategy;
-	List	   *indxsubtype;
-	List	   *indxlossy;
-	List	   *indxid;
+	ListCell   *indxqual;
+	ListCell   *indxstrategy;
+	ListCell   *indxsubtype;
+	ListCell   *indxlossy;
+	ListCell   *indxid_item;
 	int			i;
 	int			numIndices;
 	int			indexPtr;
@@ -719,8 +719,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
 	/*
 	 * get the index node information
 	 */
-	indxid = node->indxid;
-	numIndices = length(indxid);
+	indxid_item = list_head(node->indxid);
+	numIndices = length(node->indxid);
 	indexPtr = -1;
 
 	CXT1_printf("ExecInitIndexScan: context is %d\n", CurrentMemoryContext);
@@ -745,28 +745,32 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
 	/*
 	 * build the index scan keys from the index qualification
 	 */
-	indxqual = node->indxqual;
-	indxstrategy = node->indxstrategy;
-	indxsubtype = node->indxsubtype;
-	indxlossy = node->indxlossy;
+	indxqual = list_head(node->indxqual);
+	indxstrategy = list_head(node->indxstrategy);
+	indxsubtype = list_head(node->indxsubtype);
+	indxlossy = list_head(node->indxlossy);
 	for (i = 0; i < numIndices; i++)
 	{
 		List	   *quals;
 		List	   *strategies;
 		List	   *subtypes;
 		List	   *lossyflags;
+		ListCell   *qual_cell;
+		ListCell   *strategy_cell;
+		ListCell   *subtype_cell;
+		ListCell   *lossyflag_cell;
 		int			n_keys;
 		ScanKey		scan_keys;
 		ExprState **run_keys;
 		int			j;
 
-		quals = lfirst(indxqual);
+		quals = (List *) lfirst(indxqual);
 		indxqual = lnext(indxqual);
-		strategies = lfirst(indxstrategy);
+		strategies = (List *) lfirst(indxstrategy);
 		indxstrategy = lnext(indxstrategy);
-		subtypes = lfirst(indxsubtype);
+		subtypes = (List *) lfirst(indxsubtype);
 		indxsubtype = lnext(indxsubtype);
-		lossyflags = lfirst(indxlossy);
+		lossyflags = (List *) lfirst(indxlossy);
 		indxlossy = lnext(indxlossy);
 		n_keys = length(quals);
 		scan_keys = (n_keys <= 0) ? NULL :
@@ -778,6 +782,10 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
 		 * for each opclause in the given qual, convert each qual's
 		 * opclause into a single scan key
 		 */
+		qual_cell = list_head(quals);
+		strategy_cell = list_head(strategies);
+		subtype_cell = list_head(subtypes);
+		lossyflag_cell = list_head(lossyflags);
 		for (j = 0; j < n_keys; j++)
 		{
 			OpExpr	   *clause;			/* one clause of index qual */
@@ -794,14 +802,14 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
 			/*
 			 * extract clause information from the qualification
 			 */
-			clause = (OpExpr *) lfirst(quals);
-			quals = lnext(quals);
-			strategy = lfirsti(strategies);
-			strategies = lnext(strategies);
-			subtype = lfirsto(subtypes);
-			subtypes = lnext(subtypes);
-			lossy = lfirsti(lossyflags);
-			lossyflags = lnext(lossyflags);
+			clause = (OpExpr *) lfirst(qual_cell);
+			qual_cell = lnext(qual_cell);
+			strategy = lfirsti(strategy_cell);
+			strategy_cell = lnext(strategy_cell);
+			subtype = lfirsto(subtype_cell);
+			subtype_cell = lnext(subtype_cell);
+			lossy = lfirsti(lossyflag_cell);
+			lossyflag_cell = lnext(lossyflag_cell);
 
 			if (!IsA(clause, OpExpr))
 				elog(ERROR, "indxqual is not an OpExpr");
@@ -972,7 +980,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
 	 */
 	for (i = 0; i < numIndices; i++)
 	{
-		Oid			indexOid = lfirsto(indxid);
+		Oid			indexOid = lfirsto(indxid_item);
 
 		indexDescs[i] = index_open(indexOid);
 		scanDescs[i] = index_beginscan(currentRelation,
@@ -980,7 +988,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
 									   estate->es_snapshot,
 									   numScanKeys[i],
 									   scanKeys[i]);
-		indxid = lnext(indxid);
+		indxid_item = lnext(indxid_item);
 	}
 
 	indexstate->iss_RelationDescs = indexDescs;
diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c
index 9c44102611a6d8fd528e5426909065f1e76da833..e9ca17317e30625a3a8ef8d1f225851874e075b2 100644
--- a/src/backend/executor/nodeMergejoin.c
+++ b/src/backend/executor/nodeMergejoin.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.64 2004/03/17 01:02:23 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.65 2004/05/26 04:41:16 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -104,10 +104,10 @@ static void
 MJFormSkipQuals(List *qualList, List **ltQuals, List **gtQuals,
 				PlanState *parent)
 {
-	List	   *ltexprs,
-			   *gtexprs,
-			   *ltcdr,
-			   *gtcdr;
+	List		*ltexprs,
+				*gtexprs;
+	ListCell	*ltcdr,
+				*gtcdr;
 
 	/*
 	 * Make modifiable copies of the qualList.
@@ -119,8 +119,7 @@ MJFormSkipQuals(List *qualList, List **ltQuals, List **gtQuals,
 	 * Scan both lists in parallel, so that we can update the operators
 	 * with the minimum number of syscache searches.
 	 */
-	ltcdr = ltexprs;
-	foreach(gtcdr, gtexprs)
+	forboth(ltcdr, ltexprs, gtcdr, gtexprs)
 	{
 		OpExpr	   *ltop = (OpExpr *) lfirst(ltcdr);
 		OpExpr	   *gtop = (OpExpr *) lfirst(gtcdr);
@@ -140,8 +139,6 @@ MJFormSkipQuals(List *qualList, List **ltQuals, List **gtQuals,
 							  &gtop->opno,
 							  &ltop->opfuncid,
 							  &gtop->opfuncid);
-
-		ltcdr = lnext(ltcdr);
 	}
 
 	/*
@@ -173,8 +170,8 @@ MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
 {
 	bool		result;
 	MemoryContext oldContext;
-	List	   *clause;
-	List	   *eqclause;
+	ListCell   *clause;
+	ListCell   *eqclause;
 
 	/*
 	 * Do expression eval in short-lived context.
@@ -188,8 +185,12 @@ MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
 	 */
 	result = false;				/* assume 'false' result */
 
-	eqclause = eqQual;
-	foreach(clause, compareQual)
+	/*
+	 * We can't run out of one list before the other
+	 */
+	Assert(length(compareQual) == length(eqQual));
+
+	forboth(clause, compareQual, eqclause, eqQual)
 	{
 		ExprState  *clauseexpr = (ExprState *) lfirst(clause);
 		ExprState  *eqclauseexpr = (ExprState *) lfirst(eqclause);
@@ -220,8 +221,6 @@ MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
 
 		if (!DatumGetBool(const_value) || isNull)
 			break;				/* return false */
-
-		eqclause = lnext(eqclause);
 	}
 
 	MemoryContextSwitchTo(oldContext);
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index 8c667b70e7851e19478b2ddab55b15598dc93bea..d7db23b2c3e2f321bf8bf0387f18313a546afd30 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.61 2004/03/17 01:02:23 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.62 2004/05/26 04:41:16 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -212,8 +212,8 @@ ExecScanSubPlan(SubPlanState *node,
 	TupleTableSlot *slot;
 	Datum		result;
 	bool		found = false;	/* TRUE if got at least one subplan tuple */
-	List	   *pvar;
-	List	   *lst;
+	ListCell   *pvar;
+	ListCell   *l;
 	ArrayBuildState *astate = NULL;
 
 	/*
@@ -228,21 +228,19 @@ ExecScanSubPlan(SubPlanState *node,
 	 * calculation we have to do is done in the parent econtext, since the
 	 * Param values don't need to have per-query lifetime.)
 	 */
-	pvar = node->args;
-	foreach(lst, subplan->parParam)
+	Assert(length(subplan->parParam) == length(node->args));
+
+	forboth(l, subplan->parParam, pvar, node->args)
 	{
-		int			paramid = lfirsti(lst);
+		int			paramid = lfirst_int(l);
 		ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
 
-		Assert(pvar != NIL);
 		prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar),
 											   econtext,
 											   &(prm->isnull),
 											   NULL);
-		pvar = lnext(pvar);
 		planstate->chgParam = bms_add_member(planstate->chgParam, paramid);
 	}
-	Assert(pvar == NIL);
 
 	ExecReScan(planstate, NULL);
 
@@ -278,7 +276,7 @@ ExecScanSubPlan(SubPlanState *node,
 		Datum		rowresult = BoolGetDatum(!useOr);
 		bool		rownull = false;
 		int			col = 1;
-		List	   *plst;
+		ListCell   *plst;
 
 		if (subLinkType == EXISTS_SUBLINK)
 		{
@@ -343,11 +341,12 @@ ExecScanSubPlan(SubPlanState *node,
 		 * For ALL, ANY, and MULTIEXPR sublinks, iterate over combining
 		 * operators for columns of tuple.
 		 */
-		plst = subplan->paramIds;
-		foreach(lst, node->exprs)
+		Assert(length(node->exprs) == length(subplan->paramIds));
+
+		forboth(l, node->exprs, plst, subplan->paramIds)
 		{
-			ExprState  *exprstate = (ExprState *) lfirst(lst);
-			int			paramid = lfirsti(plst);
+			ExprState  *exprstate = (ExprState *) lfirst(l);
+			int			paramid = lfirst_int(plst);
 			ParamExecData *prmdata;
 			Datum		expresult;
 			bool		expnull;
@@ -400,7 +399,6 @@ ExecScanSubPlan(SubPlanState *node,
 				}
 			}
 
-			plst = lnext(plst);
 			col++;
 		}
 
@@ -559,7 +557,7 @@ buildSubPlanHash(SubPlanState *node)
 		HeapTuple	tup = slot->val;
 		TupleDesc	tdesc = slot->ttc_tupleDescriptor;
 		int			col = 1;
-		List	   *plst;
+		ListCell   *plst;
 		bool		isnew;
 
 		/*
@@ -737,7 +735,7 @@ ExecInitSubPlan(SubPlanState *node, EState *estate)
 	 */
 	if (subplan->setParam != NIL)
 	{
-		List	   *lst;
+		ListCell   *lst;
 
 		foreach(lst, subplan->setParam)
 		{
@@ -762,8 +760,8 @@ ExecInitSubPlan(SubPlanState *node, EState *estate)
 		List	   *lefttlist,
 				   *righttlist,
 				   *leftptlist,
-				   *rightptlist,
-				   *lexpr;
+				   *rightptlist;
+		ListCell   *lexpr;
 
 		/* We need a memory context to hold the hash table(s) */
 		node->tablecxt =
@@ -815,7 +813,7 @@ ExecInitSubPlan(SubPlanState *node, EState *estate)
 			Assert(length(fstate->args) == 2);
 
 			/* Process lefthand argument */
-			exstate = (ExprState *) lfirst(fstate->args);
+			exstate = (ExprState *) linitial(fstate->args);
 			expr = exstate->expr;
 			tle = makeTargetEntry(makeResdom(i,
 											 exprType((Node *) expr),
@@ -914,7 +912,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
 	SubLinkType subLinkType = subplan->subLinkType;
 	MemoryContext oldcontext;
 	TupleTableSlot *slot;
-	List	   *lst;
+	ListCell	*l;
 	bool		found = false;
 	ArrayBuildState *astate = NULL;
 
@@ -941,7 +939,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
 		if (subLinkType == EXISTS_SUBLINK)
 		{
 			/* There can be only one param... */
-			int			paramid = lfirsti(subplan->setParam);
+			int			paramid = linitial_int(subplan->setParam);
 			ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
 
 			prm->execPlan = NULL;
@@ -992,9 +990,9 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
 		/*
 		 * Now set all the setParam params from the columns of the tuple
 		 */
-		foreach(lst, subplan->setParam)
+		foreach(l, subplan->setParam)
 		{
-			int			paramid = lfirsti(lst);
+			int			paramid = lfirsti(l);
 			ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
 
 			prm->execPlan = NULL;
@@ -1008,7 +1006,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
 		if (subLinkType == EXISTS_SUBLINK)
 		{
 			/* There can be only one param... */
-			int			paramid = lfirsti(subplan->setParam);
+			int			paramid = linitial_int(subplan->setParam);
 			ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
 
 			prm->execPlan = NULL;
@@ -1017,9 +1015,9 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
 		}
 		else
 		{
-			foreach(lst, subplan->setParam)
+			foreach(l, subplan->setParam)
 			{
-				int			paramid = lfirsti(lst);
+				int			paramid = lfirsti(l);
 				ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
 
 				prm->execPlan = NULL;
@@ -1031,7 +1029,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
 	else if (subLinkType == ARRAY_SUBLINK)
 	{
 		/* There can be only one param... */
-		int			paramid = lfirsti(subplan->setParam);
+		int			paramid = linitial_int(subplan->setParam);
 		ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
 
 		Assert(astate != NULL);
@@ -1074,7 +1072,7 @@ ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
 	PlanState  *planstate = node->planstate;
 	SubPlan    *subplan = (SubPlan *) node->xprstate.expr;
 	EState	   *estate = parent->state;
-	List	   *lst;
+	ListCell   *l;
 
 	/* sanity checks */
 	if (subplan->parParam != NIL)
@@ -1091,9 +1089,9 @@ ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
 	/*
 	 * Mark this subplan's output parameters as needing recalculation
 	 */
-	foreach(lst, subplan->setParam)
+	foreach(l, subplan->setParam)
 	{
-		int			paramid = lfirsti(lst);
+		int			paramid = lfirsti(l);
 		ParamExecData *prm = &(estate->es_param_exec_vals[paramid]);
 
 		prm->execPlan = node;
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index ee928deff5de0e3caa7bd6582faf09d7ac5fc191..0d321b0866605ab59c98d7922cbcc8427ebb59a5 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.37 2004/04/21 18:24:26 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.38 2004/05/26 04:41:16 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -45,18 +45,18 @@ TidListCreate(TidScanState *tidstate)
 	ExprContext *econtext = tidstate->ss.ps.ps_ExprContext;
 	ItemPointerData *tidList;
 	int			numTids = 0;
-	List	   *lst;
+	ListCell   *l;
 
 	tidList = (ItemPointerData *)
 		palloc(length(tidstate->tss_tideval) * sizeof(ItemPointerData));
 
-	foreach(lst, evalList)
+	foreach(l, evalList)
 	{
 		ItemPointer itemptr;
 		bool		isNull;
 
 		itemptr = (ItemPointer)
-			DatumGetPointer(ExecEvalExprSwitchContext(lfirst(lst),
+			DatumGetPointer(ExecEvalExprSwitchContext(lfirst(l),
 													  econtext,
 													  &isNull,
 													  NULL));
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index bcf7f8d52b68cffd345aee4f0f3c580840a1c4f8..4d8fade3d6456e1bd52631c21574dba7b9538f02 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.113 2004/04/01 21:28:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/spi.c,v 1.114 2004/05/26 04:41:16 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -744,8 +744,8 @@ SPI_cursor_open(const char *name, void *plan, Datum *Values, const char *Nulls)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_CURSOR_DEFINITION),
 				 errmsg("cannot open multi-query plan as cursor")));
-	queryTree = (Query *) lfirst((List *) lfirst(qtlist));
-	planTree = (Plan *) lfirst(ptlist);
+	queryTree = (Query *) linitial((List *) linitial(qtlist));
+	planTree = (Plan *) linitial(ptlist);
 
 	if (queryTree->commandType != CMD_SELECT)
 		ereport(ERROR,
@@ -953,7 +953,7 @@ SPI_is_cursor_plan(void *plan)
 	qtlist = spiplan->qtlist;
 	if (length(spiplan->ptlist) == 1 && length(qtlist) == 1)
 	{
-		Query *queryTree = (Query *) lfirst((List *) lfirst(qtlist));
+		Query *queryTree = (Query *) linitial((List *) linitial(qtlist));
 
 		if (queryTree->commandType == CMD_SELECT && queryTree->into == NULL)
 			return true;
@@ -1062,7 +1062,7 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan)
 	List	   *raw_parsetree_list;
 	List	   *query_list_list;
 	List	   *plan_list;
-	List	   *list_item;
+	ListCell   *list_item;
 	ErrorContextCallback spierrcontext;
 	int			nargs = 0;
 	Oid		   *argtypes = NULL;
@@ -1110,7 +1110,7 @@ _SPI_execute(const char *src, int tcount, _SPI_plan *plan)
 	{
 		Node	   *parsetree = (Node *) lfirst(list_item);
 		List	   *query_list;
-		List	   *query_list_item;
+		ListCell   *query_list_item;
 
 		query_list = pg_analyze_and_rewrite(parsetree, argtypes, nargs);
 
@@ -1207,8 +1207,8 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
 				  bool useCurrentSnapshot, int tcount)
 {
 	List	   *query_list_list = plan->qtlist;
-	List	   *plan_list = plan->ptlist;
-	List	   *query_list_list_item;
+	ListCell   *plan_list_item = list_head(plan->ptlist);
+	ListCell   *query_list_list_item;
 	ErrorContextCallback spierrcontext;
 	int			nargs = plan->nargs;
 	int			res = 0;
@@ -1254,7 +1254,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
 	foreach(query_list_list_item, query_list_list)
 	{
 		List	   *query_list = lfirst(query_list_list_item);
-		List	   *query_list_item;
+		ListCell   *query_list_item;
 
 		/* Reset state for each original parsetree */
 		/* (at most one of its querytrees will be marked canSetTag) */
@@ -1270,8 +1270,8 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, const char *Nulls,
 			QueryDesc  *qdesc;
 			DestReceiver *dest;
 
-			planTree = lfirst(plan_list);
-			plan_list = lnext(plan_list);
+			planTree = lfirst(plan_list_item);
+			plan_list_item = lnext(plan_list_item);
 
 			dest = CreateDestReceiver(queryTree->canSetTag ? SPI : None, NULL);
 			if (queryTree->commandType == CMD_UTILITY)
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c
index 8b8fa6abf96a5fde2c7ebd1a1ff9a04503a06a0c..dda111fc6885dcc038b5bf304bed5b9d46364ed5 100644
--- a/src/backend/libpq/crypt.c
+++ b/src/backend/libpq/crypt.c
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.58 2003/11/29 19:51:49 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.59 2004/05/26 04:41:18 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -36,14 +36,14 @@ md5_crypt_verify(const Port *port, const char *user, char *client_pass)
 			   *crypt_pwd;
 	int			retval = STATUS_ERROR;
 	List	  **line;
-	List	   *token;
+	ListCell   *token;
 	char	   *crypt_client_pass = client_pass;
 
 	if ((line = get_user_line(user)) == NULL)
 		return STATUS_ERROR;
 
-	/* Skip over line number and username */
-	token = lnext(lnext(*line));
+	/* Skip over username */
+	token = lnext(list_head(*line));
 	if (token)
 	{
 		shadow_pass = lfirst(token);
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index d4204acfd576acaec5d7913b921381d5147622e9..25666af6902df92d948f6552778dc13a5ceff98d 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -10,12 +10,14 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.122 2004/05/25 19:11:14 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.123 2004/05/26 04:41:18 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
+#define DISABLE_LIST_COMPAT
+
 #include <errno.h>
 #include <pwd.h>
 #include <fcntl.h>
@@ -63,11 +65,19 @@
  * one string per token on the line.  Note there will always be at least
  * one token, since blank lines are not entered in the data structure.
  */
-static List *hba_lines = NIL;	/* pre-parsed contents of hba file */
-static List *ident_lines = NIL; /* pre-parsed contents of ident file */
-static List *group_lines = NIL; /* pre-parsed contents of group file */
-static List *user_lines = NIL;	/* pre-parsed contents of user password
-								 * file */
+
+/* pre-parsed content of CONF_FILE and corresponding line #s */
+static List *hba_lines			= NIL;
+static List *hba_line_nums		= NIL;
+/* pre-parsed content of USERMAP_FILE and corresponding line #s */
+static List *ident_lines		= NIL;
+static List *ident_line_nums	= NIL;
+/* pre-parsed content of group file and corresponding line #s */
+static List *group_lines		= NIL;
+static List *group_line_nums	= NIL;
+/* pre-parsed content of user passwd file and corresponding line #s */
+static List *user_lines			= NIL;
+static List *user_line_nums		= NIL;
 
 /* sorted entries so we can do binary search lookups */
 static List **user_sorted = NULL;		/* sorted user list, for bsearch() */
@@ -76,7 +86,7 @@ static List **group_sorted = NULL;		/* sorted group list, for
 static int	user_length;
 static int	group_length;
 
-static List *tokenize_file(FILE *file);
+static void tokenize_file(FILE *file, List **lines, List **line_nums);
 static char *tokenize_inc_file(const char *inc_filename);
 
 /*
@@ -250,28 +260,45 @@ next_token_expand(FILE *file)
  * Free memory used by lines/tokens (i.e., structure built by tokenize_file)
  */
 static void
-free_lines(List **lines)
+free_lines(List **lines, List **line_nums)
 {
+	/*
+	 * Either both must be non-NULL, or both must be NULL
+	 */
+	Assert((*lines != NIL && *line_nums != NIL) ||
+		   (*lines == NIL && *line_nums == NIL));
+
 	if (*lines)
 	{
-		List	   *line,
-				   *token;
+		/*
+		 * "lines" is a list of lists; each of those sublists consists
+		 * of palloc'ed tokens, so we want to free each pointed-to
+		 * token in a sublist, followed by the sublist itself, and
+		 * finally the whole list.
+		 */
+		ListCell   *line;
 
 		foreach(line, *lines)
 		{
 			List	   *ln = lfirst(line);
+			ListCell   *token;
 
-			/* free the pstrdup'd tokens (don't try it on the line number) */
-			foreach(token, lnext(ln))
+			foreach(token, ln)
 				pfree(lfirst(token));
 			/* free the sublist structure itself */
-			freeList(ln);
+			list_free(ln);
 		}
 		/* free the list structure itself */
-		freeList(*lines);
+		list_free(*lines);
 		/* clear the static variable */
 		*lines = NIL;
 	}
+
+	if (*line_nums)
+	{
+		list_free(*line_nums);
+		*line_nums = NIL;
+	}
 }
 
 
@@ -281,7 +308,8 @@ tokenize_inc_file(const char *inc_filename)
 	char	   *inc_fullname;
 	FILE	   *inc_file;
 	List	   *inc_lines;
-	List	   *line;
+	List	   *inc_line_nums;
+	ListCell   *line;
 	char	   *comma_str = pstrdup("");
 
 	inc_fullname = (char *) palloc(strlen(DataDir) + 1 +
@@ -305,17 +333,16 @@ tokenize_inc_file(const char *inc_filename)
 	pfree(inc_fullname);
 
 	/* There is possible recursion here if the file contains @ */
-	inc_lines = tokenize_file(inc_file);
+	tokenize_file(inc_file, &inc_lines, &inc_line_nums);
 	FreeFile(inc_file);
 
 	/* Create comma-separate string from List */
 	foreach(line, inc_lines)
 	{
-		List	   *ln = lfirst(line);
-		List	   *token;
+		List		   *token_list = (List *) lfirst(line);
+		ListCell	   *token;
 
-		/* First entry is line number */
-		foreach(token, lnext(ln))
+		foreach(token, token_list)
 		{
 			if (strlen(comma_str))
 			{
@@ -328,24 +355,26 @@ tokenize_inc_file(const char *inc_filename)
 		}
 	}
 
-	free_lines(&inc_lines);
+	free_lines(&inc_lines, &inc_line_nums);
 
 	return comma_str;
 }
 
 
-
 /*
- *	Read the given file and create a list of line sublists.
+ * Tokenize the given file, storing the resulting data into two lists:
+ * a list of sublists, each sublist containing the tokens in a line of
+ * the file, and a list of line numbers.
  */
-static List *
-tokenize_file(FILE *file)
+static void
+tokenize_file(FILE *file, List **lines, List **line_nums)
 {
-	List	   *lines = NIL;
-	List	   *next_line = NIL;
+	List	   *current_line = NIL;
 	int			line_number = 1;
 	char	   *buf;
 
+	*lines = *line_nums = NIL;
+
 	while (!feof(file))
 	{
 		buf = next_token_expand(file);
@@ -353,27 +382,27 @@ tokenize_file(FILE *file)
 		/* add token to list, unless we are at EOL or comment start */
 		if (buf[0] != '\0')
 		{
-			if (next_line == NIL)
+			if (current_line == NIL)
+			{
+				/* make a new line List, record its line number */
+				current_line = lappend(current_line, buf);
+				*lines = lappend(*lines, current_line);
+				*line_nums = lappend_int(*line_nums, line_number);
+			}
+			else
 			{
-				/* make a new line List */
-				next_line = makeListi1(line_number);
-				lines = lappend(lines, next_line);
+				/* append token to current line's list */
+				current_line = lappend(current_line, buf);
 			}
-			/* append token to current line's list */
-			next_line = lappend(next_line, buf);
 		}
 		else
 		{
 			/* we are at real or logical EOL, so force a new line List */
-			next_line = NIL;
-		}
-
-		/* Advance line number whenever we reach EOL */
-		if (next_line == NIL)
+			current_line = NIL;
+			/* Advance line number whenever we reach EOL */
 			line_number++;
+		}
 	}
-
-	return lines;
 }
 
 
@@ -385,9 +414,8 @@ tokenize_file(FILE *file)
 static int
 user_group_qsort_cmp(const void *list1, const void *list2)
 {
-	/* first node is line number */
-	char	   *user1 = lfirst(lnext(*(List **) list1));
-	char	   *user2 = lfirst(lnext(*(List **) list2));
+	char	   *user1 = linitial(*(List **) list1);
+	char	   *user2 = linitial(*(List **) list2);
 
 	return strcmp(user1, user2);
 }
@@ -401,8 +429,7 @@ user_group_qsort_cmp(const void *list1, const void *list2)
 static int
 user_group_bsearch_cmp(const void *user, const void *list)
 {
-	/* first node is line number */
-	char	   *user2 = lfirst(lnext(*(List **) list));
+	char	   *user2 = linitial(*(List **) list);
 
 	return strcmp(user, user2);
 }
@@ -450,14 +477,18 @@ get_user_line(const char *user)
 static bool
 check_group(char *group, char *user)
 {
-	List	  **line,
-			   *l;
+	List	  **line;
 
 	if ((line = get_group_line(group)) != NULL)
 	{
-		foreach(l, lnext(lnext(*line)))
-			if (strcmp(lfirst(l), user) == 0)
-			return true;
+		ListCell *line_item;
+
+		/* skip over the group name */
+		for_each_cell(line_item, lnext(list_head(*line)))
+		{
+			if (strcmp(lfirst(line_item), user) == 0)
+				return true;
+		}
 	}
 
 	return false;
@@ -518,24 +549,24 @@ check_db(char *dbname, char *user, char *param_str)
 /*
  *	Scan the rest of a host record (after the mask field)
  *	and return the interpretation of it as *userauth_p, *auth_arg_p, and
- *	*error_p.  *line points to the next token of the line, and is
+ *	*error_p.  *line_item points to the next token of the line, and is
  *	advanced over successfully-read tokens.
  */
 static void
-parse_hba_auth(List **line, UserAuth *userauth_p, char **auth_arg_p,
-			   bool *error_p)
+parse_hba_auth(ListCell **line_item, UserAuth *userauth_p,
+			   char **auth_arg_p, bool *error_p)
 {
 	char	   *token;
 
 	*auth_arg_p = NULL;
 
-	/* Get authentication type token. */
-	if (!*line)
+	if (!*line_item)
 	{
 		*error_p = true;
 		return;
 	}
-	token = lfirst(*line);
+
+	token = lfirst(*line_item);
 	if (strcmp(token, "trust") == 0)
 		*userauth_p = uaTrust;
 	else if (strcmp(token, "ident") == 0)
@@ -561,16 +592,16 @@ parse_hba_auth(List **line, UserAuth *userauth_p, char **auth_arg_p,
 		*error_p = true;
 		return;
 	}
-	*line = lnext(*line);
+	*line_item = lnext(*line_item);
 
 	/* Get the authentication argument token, if any */
-	if (*line)
+	if (*line_item)
 	{
-		token = lfirst(*line);
+		token = lfirst(*line_item);
 		*auth_arg_p = pstrdup(token);
-		*line = lnext(*line);
+		*line_item = lnext(*line_item);
 		/* If there is more on the line, it is an error */
-		if (*line)
+		if (*line_item)
 			*error_p = true;
 	}
 }
@@ -587,9 +618,9 @@ parse_hba_auth(List **line, UserAuth *userauth_p, char **auth_arg_p,
  *	leave *error_p as it was.
  */
 static void
-parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
+parse_hba(List *line, int line_num, hbaPort *port,
+		  bool *found_p, bool *error_p)
 {
-	int			line_number;
 	char	   *token;
 	char	   *db;
 	char	   *user;
@@ -599,33 +630,32 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 	struct sockaddr_storage addr;
 	struct sockaddr_storage mask;
 	char	   *cidr_slash;
+	ListCell   *line_item;
 
-	Assert(line != NIL);
-	line_number = lfirsti(line);
-	line = lnext(line);
-	Assert(line != NIL);
+	line_item = list_head(line);
 	/* Check the record type. */
-	token = lfirst(line);
+	token = lfirst(line_item);
 	if (strcmp(token, "local") == 0)
 	{
 		/* Get the database. */
-		line = lnext(line);
-		if (!line)
+		line_item = lnext(line_item);
+		if (!line_item)
 			goto hba_syntax;
-		db = lfirst(line);
+		db = lfirst(line_item);
 
 		/* Get the user. */
-		line = lnext(line);
-		if (!line)
+		line_item = lnext(line_item);
+		if (!line_item)
 			goto hba_syntax;
-		user = lfirst(line);
+		user = lfirst(line_item);
 
-		line = lnext(line);
-		if (!line)
+		line_item = lnext(line_item);
+		if (!line_item)
 			goto hba_syntax;
 
 		/* Read the rest of the line. */
-		parse_hba_auth(&line, &port->auth_method, &port->auth_arg, error_p);
+		parse_hba_auth(&line_item, &port->auth_method,
+					   &port->auth_arg, error_p);
 		if (*error_p)
 			goto hba_syntax;
 
@@ -669,22 +699,22 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 #endif
 
 		/* Get the database. */
-		line = lnext(line);
-		if (!line)
+		line_item = lnext(line_item);
+		if (!line_item)
 			goto hba_syntax;
-		db = lfirst(line);
+		db = lfirst(line_item);
 
 		/* Get the user. */
-		line = lnext(line);
-		if (!line)
+		line_item = lnext(line_item);
+		if (!line_item)
 			goto hba_syntax;
-		user = lfirst(line);
+		user = lfirst(line_item);
 
 		/* Read the IP address field. (with or without CIDR netmask) */
-		line = lnext(line);
-		if (!line)
+		line_item = lnext(line_item);
+		if (!line_item)
 			goto hba_syntax;
-		token = lfirst(line);
+		token = lfirst(line_item);
 
 		/* Check if it has a CIDR suffix and if so isolate it */
 		cidr_slash = strchr(token, '/');
@@ -707,7 +737,7 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 			ereport(LOG,
 					(errcode(ERRCODE_CONFIG_FILE_ERROR),
 					 errmsg("invalid IP address \"%s\" in pg_hba.conf file line %d: %s",
-							token, line_number, gai_strerror(ret))));
+							token, line_num, gai_strerror(ret))));
 			if (cidr_slash)
 				*cidr_slash = '/';
 			if (gai_result)
@@ -730,10 +760,10 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 		else
 		{
 			/* Read the mask field. */
-			line = lnext(line);
-			if (!line)
+			line_item = lnext(line_item);
+			if (!line_item)
 				goto hba_syntax;
-			token = lfirst(line);
+			token = lfirst(line_item);
 
 			ret = getaddrinfo_all(token, NULL, &hints, &gai_result);
 			if (ret || !gai_result)
@@ -741,7 +771,7 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 				ereport(LOG,
 						(errcode(ERRCODE_CONFIG_FILE_ERROR),
 						 errmsg("invalid IP mask \"%s\" in pg_hba.conf file line %d: %s",
-								token, line_number, gai_strerror(ret))));
+								token, line_num, gai_strerror(ret))));
 				if (gai_result)
 					freeaddrinfo_all(hints.ai_family, gai_result);
 				goto hba_other_error;
@@ -755,7 +785,7 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 				ereport(LOG,
 						(errcode(ERRCODE_CONFIG_FILE_ERROR),
 						 errmsg("IP address and mask do not match in pg_hba.conf file line %d",
-								line_number)));
+								line_num)));
 				goto hba_other_error;
 			}
 		}
@@ -787,10 +817,11 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 			return;
 
 		/* Read the rest of the line. */
-		line = lnext(line);
-		if (!line)
+		line_item = lnext(line_item);
+		if (!line_item)
 			goto hba_syntax;
-		parse_hba_auth(&line, &port->auth_method, &port->auth_arg, error_p);
+		parse_hba_auth(&line_item, &port->auth_method,
+					   &port->auth_arg, error_p);
 		if (*error_p)
 			goto hba_syntax;
 	}
@@ -808,16 +839,16 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
 	return;
 
 hba_syntax:
-	if (line)
+	if (line_item)
 		ereport(LOG,
 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
 				 errmsg("invalid entry in pg_hba.conf file at line %d, token \"%s\"",
-						line_number, (const char *) lfirst(line))));
+						line_num, (char *) lfirst(line_item))));
 	else
 		ereport(LOG,
 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
-			errmsg("missing field in pg_hba.conf file at end of line %d",
-				   line_number)));
+				 errmsg("missing field in pg_hba.conf file at end of line %d",
+						line_num)));
 
 	/* Come here if suitable message already logged */
 hba_other_error:
@@ -834,11 +865,13 @@ check_hba(hbaPort *port)
 {
 	bool		found_entry = false;
 	bool		error = false;
-	List	   *line;
+	ListCell   *line;
+	ListCell   *line_num;
 
-	foreach(line, hba_lines)
+	forboth(line, hba_lines, line_num, hba_line_nums)
 	{
-		parse_hba(lfirst(line), port, &found_entry, &error);
+		parse_hba(lfirst(line), lfirst_int(line_num),
+				  port, &found_entry, &error);
 		if (found_entry || error)
 			break;
 	}
@@ -911,11 +944,10 @@ void
 load_group(void)
 {
 	FILE	   *group_file;
-	List	   *line;
 
 	/* Discard any old data */
-	if (group_lines)
-		free_lines(&group_lines);
+	if (group_lines || group_line_nums)
+		free_lines(&group_lines, &group_line_nums);
 	if (group_sorted)
 		pfree(group_sorted);
 	group_sorted = NULL;
@@ -924,14 +956,15 @@ load_group(void)
 	group_file = group_openfile();
 	if (!group_file)
 		return;
-	group_lines = tokenize_file(group_file);
+	tokenize_file(group_file, &group_lines, &group_line_nums);
 	FreeFile(group_file);
 
 	/* create sorted lines for binary searching */
-	group_length = length(group_lines);
+	group_length = list_length(group_lines);
 	if (group_length)
 	{
 		int			i = 0;
+		ListCell   *line;
 
 		group_sorted = palloc(group_length * sizeof(List *));
 
@@ -953,11 +986,10 @@ void
 load_user(void)
 {
 	FILE	   *user_file;
-	List	   *line;
 
 	/* Discard any old data */
-	if (user_lines)
-		free_lines(&user_lines);
+	if (user_lines || user_line_nums)
+		free_lines(&user_lines, &user_line_nums);
 	if (user_sorted)
 		pfree(user_sorted);
 	user_sorted = NULL;
@@ -966,14 +998,15 @@ load_user(void)
 	user_file = user_openfile();
 	if (!user_file)
 		return;
-	user_lines = tokenize_file(user_file);
+	tokenize_file(user_file, &user_lines, &user_line_nums);
 	FreeFile(user_file);
 
 	/* create sorted lines for binary searching */
-	user_length = length(user_lines);
+	user_length = list_length(user_lines);
 	if (user_length)
 	{
 		int			i = 0;
+		ListCell   *line;
 
 		user_sorted = palloc(user_length * sizeof(List *));
 
@@ -1002,8 +1035,8 @@ load_hba(void)
 	FILE	   *file;			/* The config file we have to read */
 	char	   *conf_file;		/* The name of the config file */
 
-	if (hba_lines)
-		free_lines(&hba_lines);
+	if (hba_lines || hba_line_nums)
+		free_lines(&hba_lines, &hba_line_nums);
 
 	/* Put together the full pathname to the config file. */
 	bufsize = (strlen(DataDir) + strlen(CONF_FILE) + 2) * sizeof(char);
@@ -1017,7 +1050,7 @@ load_hba(void)
 				 errmsg("could not open configuration file \"%s\": %m",
 						conf_file)));
 
-	hba_lines = tokenize_file(file);
+	tokenize_file(file, &hba_lines, &hba_line_nums);
 	FreeFile(file);
 	pfree(conf_file);
 }
@@ -1030,10 +1063,11 @@ load_hba(void)
  *	*found_p and *error_p are set according to our results.
  */
 static void
-parse_ident_usermap(List *line, const char *usermap_name, const char *pg_user,
-					const char *ident_user, bool *found_p, bool *error_p)
+parse_ident_usermap(List *line, int line_number, const char *usermap_name,
+					const char *pg_user, const char *ident_user,
+					bool *found_p, bool *error_p)
 {
-	int			line_number;
+	ListCell   *line_item;
 	char	   *token;
 	char	   *file_map;
 	char	   *file_pguser;
@@ -1043,26 +1077,24 @@ parse_ident_usermap(List *line, const char *usermap_name, const char *pg_user,
 	*error_p = false;
 
 	Assert(line != NIL);
-	line_number = lfirsti(line);
-	line = lnext(line);
-	Assert(line != NIL);
+	line_item = list_head(line);
 
 	/* Get the map token (must exist) */
-	token = lfirst(line);
+	token = lfirst(line_item);
 	file_map = token;
 
 	/* Get the ident user token (must be provided) */
-	line = lnext(line);
+	line_item = lnext(line_item);
 	if (!line)
 		goto ident_syntax;
-	token = lfirst(line);
+	token = lfirst(line_item);
 	file_ident_user = token;
 
 	/* Get the PG username token */
-	line = lnext(line);
+	line_item = lnext(line_item);
 	if (!line)
 		goto ident_syntax;
-	token = lfirst(line);
+	token = lfirst(line_item);
 	file_pguser = token;
 
 	/* Match? */
@@ -1073,11 +1105,11 @@ parse_ident_usermap(List *line, const char *usermap_name, const char *pg_user,
 	return;
 
 ident_syntax:
-	if (line)
+	if (line_item)
 		ereport(LOG,
 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
 				 errmsg("invalid entry in pg_ident.conf file at line %d, token \"%s\"",
-						line_number, (const char *) lfirst(line))));
+						line_number, (const char *) lfirst(line_item))));
 	else
 		ereport(LOG,
 				(errcode(ERRCODE_CONFIG_FILE_ERROR),
@@ -1105,7 +1137,6 @@ check_ident_usermap(const char *usermap_name,
 					const char *pg_user,
 					const char *ident_user)
 {
-	List	   *line;
 	bool		found_entry = false,
 				error = false;
 
@@ -1125,10 +1156,13 @@ check_ident_usermap(const char *usermap_name,
 	}
 	else
 	{
-		foreach(line, ident_lines)
+		ListCell *line_cell, *num_cell;
+
+		forboth(line_cell, ident_lines, num_cell, ident_line_nums)
 		{
-			parse_ident_usermap(lfirst(line), usermap_name, pg_user,
-								ident_user, &found_entry, &error);
+			parse_ident_usermap(lfirst(line_cell), lfirst_int(num_cell),
+								usermap_name, pg_user, ident_user,
+								&found_entry, &error);
 			if (found_entry || error)
 				break;
 		}
@@ -1148,8 +1182,8 @@ load_ident(void)
 								 * read */
 	int			bufsize;
 
-	if (ident_lines)
-		free_lines(&ident_lines);
+	if (ident_lines || ident_line_nums)
+		free_lines(&ident_lines, &ident_line_nums);
 
 	/* put together the full pathname to the map file */
 	bufsize = (strlen(DataDir) + strlen(USERMAP_FILE) + 2) * sizeof(char);
@@ -1166,7 +1200,7 @@ load_ident(void)
 	}
 	else
 	{
-		ident_lines = tokenize_file(file);
+		tokenize_file(file, &ident_lines, &ident_line_nums);
 		FreeFile(file);
 	}
 	pfree(map_file);
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 91fb3b08343ca38dcb61ea8f145598c84f20196e..21cef8879221dd90ebc3f3da22473784f88e3205 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,11 +15,13 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.281 2004/05/10 22:44:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.282 2004/05/26 04:41:18 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
 
+#define DISABLE_LIST_COMPAT
+
 #include "postgres.h"
 
 #include "nodes/parsenodes.h"
@@ -43,14 +45,6 @@
 #define COPY_NODE_FIELD(fldname) \
 	(newnode->fldname = copyObject(from->fldname))
 
-/* Copy a field that is a pointer to a list of integers */
-#define COPY_INTLIST_FIELD(fldname) \
-	(newnode->fldname = listCopy(from->fldname))
-
-/* Copy a field that is a pointer to a list of Oids */
-#define COPY_OIDLIST_FIELD(fldname) \
-	(newnode->fldname = listCopy(from->fldname))
-
 /* Copy a field that is a pointer to a Bitmapset */
 #define COPY_BITMAPSET_FIELD(fldname) \
 	(newnode->fldname = bms_copy(from->fldname))
@@ -68,46 +62,6 @@
 	} while (0)
 
 
-/*
- * listCopy
- *	  This copy function only copies the "cons-cells" of the list, not the
- *	  pointed-to objects.  (Use copyObject if you want a "deep" copy.)
- *
- *	  We also use this function for copying lists of integers and Oids,
- *	  which is notationally a bit ugly, but perfectly safe.
- *
- *	  Note that copyObject will surely coredump if applied to a list
- *	  of integers or Oids!
- */
-List *
-listCopy(List *list)
-{
-	List	   *newlist,
-			   *oldl,
-			   *newcell,
-			   *prev;
-
-	/* rather ugly coding for speed... */
-	if (list == NIL)
-		return NIL;
-
-	newcell = makeNode(List);
-	newcell->elem = list->elem;
-
-	newlist = prev = newcell;
-
-	foreach(oldl, lnext(list))
-	{
-		newcell = makeNode(List);
-		newcell->elem = oldl->elem;
-		prev->next = newcell;
-		prev = newcell;
-	}
-	prev->next = NIL;
-
-	return newlist;
-}
-
 /* ****************************************************************
  *					 plannodes.h copy functions
  * ****************************************************************
@@ -259,42 +213,12 @@ _copyIndexScan(IndexScan *from)
 	/*
 	 * copy remainder of node
 	 */
-	COPY_OIDLIST_FIELD(indxid);
+	COPY_NODE_FIELD(indxid);
 	COPY_NODE_FIELD(indxqual);
 	COPY_NODE_FIELD(indxqualorig);
-	/* this can become COPY_NODE_FIELD when intlists are normal objects: */
-	{
-		List	*newstrat = NIL;
-		List    *tmp;
-
-		foreach(tmp, from->indxstrategy)
-		{
-			newstrat = lappend(newstrat, listCopy(lfirst(tmp)));
-		}
-		newnode->indxstrategy = newstrat;
-	}
-	/* this can become COPY_NODE_FIELD when OID lists are normal objects: */
-	{
-		List	*newsubtype = NIL;
-		List    *tmp;
-
-		foreach(tmp, from->indxsubtype)
-		{
-			newsubtype = lappend(newsubtype, listCopy(lfirst(tmp)));
-		}
-		newnode->indxsubtype = newsubtype;
-	}
-	/* this can become COPY_NODE_FIELD when intlists are normal objects: */
-	{
-		List	*newstrat = NIL;
-		List    *tmp;
-
-		foreach(tmp, from->indxlossy)
-		{
-			newstrat = lappend(newstrat, listCopy(lfirst(tmp)));
-		}
-		newnode->indxlossy = newstrat;
-	}
+	COPY_NODE_FIELD(indxstrategy);
+	COPY_NODE_FIELD(indxsubtype);
+	COPY_NODE_FIELD(indxlossy);
 	COPY_SCALAR_FIELD(indxorderdir);
 
 	return newnode;
@@ -876,7 +800,7 @@ _copySubLink(SubLink *from)
 	COPY_SCALAR_FIELD(useOr);
 	COPY_NODE_FIELD(lefthand);
 	COPY_NODE_FIELD(operName);
-	COPY_OIDLIST_FIELD(operOids);
+	COPY_NODE_FIELD(operOids);
 	COPY_NODE_FIELD(subselect);
 
 	return newnode;
@@ -893,14 +817,14 @@ _copySubPlan(SubPlan *from)
 	COPY_SCALAR_FIELD(subLinkType);
 	COPY_SCALAR_FIELD(useOr);
 	COPY_NODE_FIELD(exprs);
-	COPY_INTLIST_FIELD(paramIds);
+	COPY_NODE_FIELD(paramIds);
 	COPY_NODE_FIELD(plan);
 	COPY_SCALAR_FIELD(plan_id);
 	COPY_NODE_FIELD(rtable);
 	COPY_SCALAR_FIELD(useHashTable);
 	COPY_SCALAR_FIELD(unknownEqFalse);
-	COPY_INTLIST_FIELD(setParam);
-	COPY_INTLIST_FIELD(parParam);
+	COPY_NODE_FIELD(setParam);
+	COPY_NODE_FIELD(parParam);
 	COPY_NODE_FIELD(args);
 
 	return newnode;
@@ -1582,7 +1506,7 @@ _copyQuery(Query *from)
 	COPY_SCALAR_FIELD(hasSubLinks);
 	COPY_NODE_FIELD(rtable);
 	COPY_NODE_FIELD(jointree);
-	COPY_INTLIST_FIELD(rowMarks);
+	COPY_NODE_FIELD(rowMarks);
 	COPY_NODE_FIELD(targetList);
 	COPY_NODE_FIELD(groupClause);
 	COPY_NODE_FIELD(havingQual);
@@ -1591,7 +1515,7 @@ _copyQuery(Query *from)
 	COPY_NODE_FIELD(limitOffset);
 	COPY_NODE_FIELD(limitCount);
 	COPY_NODE_FIELD(setOperations);
-	COPY_INTLIST_FIELD(resultRelations);
+	COPY_NODE_FIELD(resultRelations);
 	COPY_NODE_FIELD(in_info_list);
 	COPY_SCALAR_FIELD(hasJoinRTEs);
 
@@ -1679,7 +1603,7 @@ _copySetOperationStmt(SetOperationStmt *from)
 	COPY_SCALAR_FIELD(all);
 	COPY_NODE_FIELD(larg);
 	COPY_NODE_FIELD(rarg);
-	COPY_OIDLIST_FIELD(colTypes);
+	COPY_NODE_FIELD(colTypes);
 
 	return newnode;
 }
@@ -1731,7 +1655,7 @@ _copyGrantStmt(GrantStmt *from)
 	COPY_SCALAR_FIELD(is_grant);
 	COPY_SCALAR_FIELD(objtype);
 	COPY_NODE_FIELD(objects);
-	COPY_INTLIST_FIELD(privileges);
+	COPY_NODE_FIELD(privileges);
 	COPY_NODE_FIELD(grantees);
 	COPY_SCALAR_FIELD(grant_option);
 	COPY_SCALAR_FIELD(behavior);
@@ -2477,7 +2401,7 @@ _copyPrepareStmt(PrepareStmt *from)
 
 	COPY_STRING_FIELD(name);
 	COPY_NODE_FIELD(argtypes);
-	COPY_OIDLIST_FIELD(argtype_oids);
+	COPY_NODE_FIELD(argtype_oids);
 	COPY_NODE_FIELD(query);
 
 	return newnode;
@@ -2511,6 +2435,47 @@ _copyDeallocateStmt(DeallocateStmt *from)
  * ****************************************************************
  */
 
+/*
+ * Perform a deep copy of the specified list, using copyObject(). The
+ * list MUST be of type T_List; T_IntList and T_OidList nodes don't
+ * need deep copies, so they should be copied via list_copy()
+ */
+#define COPY_NODE_CELL(new, old)					\
+	(new) = (ListCell *) palloc(sizeof(ListCell));	\
+	lfirst(new) = copyObject(lfirst(old));
+
+static List *
+_copyList(List *from)
+{
+	List		*new;
+	ListCell	*curr_old;
+	ListCell	*prev_new;
+
+	Assert(list_length(from) >= 1);
+
+	new = makeNode(List);
+	new->length = from->length;
+
+	COPY_NODE_CELL(new->head, from->head);
+	prev_new = new->head;
+	curr_old = lnext(from->head);
+
+	while (curr_old)
+	{
+		COPY_NODE_CELL(prev_new->next, curr_old);
+		prev_new = prev_new->next;
+		curr_old = curr_old->next;
+	}
+	prev_new->next = NULL;
+	new->tail = prev_new;
+
+	return new;
+}
+
+/* ****************************************************************
+ *					value.h copy functions
+ * ****************************************************************
+ */
 static Value *
 _copyValue(Value *from)
 {
@@ -2752,30 +2717,21 @@ copyObject(void *from)
 		case T_Null:
 			retval = _copyValue(from);
 			break;
+
+			/*
+			 * LIST NODES
+			 */
 		case T_List:
-			{
-				List	   *list = from,
-						   *oldl,
-						   *newcell,
-						   *prev;
-
-				/* rather ugly coding for speed... */
-				/* Note the input list cannot be NIL if we got here. */
-				newcell = makeNode(List);
-				lfirst(newcell) = copyObject(lfirst(list));
-
-				retval = (void *) newcell;
-				prev = newcell;
-
-				foreach(oldl, lnext(list))
-				{
-					newcell = makeNode(List);
-					lfirst(newcell) = copyObject(lfirst(oldl));
-					prev->next = newcell;
-					prev = newcell;
-				}
-				prev->next = NIL;
-			}
+			retval = _copyList(from);
+			break;
+			/*
+			 * Lists of integers and OIDs don't need to be
+			 * deep-copied, so we perform a shallow copy via
+			 * list_copy()
+			 */
+		case T_IntList:
+		case T_OidList:
+			retval = list_copy(from);
 			break;
 
 			/*
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 19ffbb1be708ba647a1424536bf012163261f095..236061eee2a461bfe2653913f253c878fa5b5f83 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -18,11 +18,13 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.220 2004/05/10 22:44:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.221 2004/05/26 04:41:19 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
 
+#define DISABLE_LIST_COMPAT
+
 #include "postgres.h"
 
 #include "nodes/params.h"
@@ -52,20 +54,6 @@
 			return false; \
 	} while (0)
 
-/* Compare a field that is a pointer to a list of integers */
-#define COMPARE_INTLIST_FIELD(fldname) \
-	do { \
-		if (!equali(a->fldname, b->fldname)) \
-			return false; \
-	} while (0)
-
-/* Compare a field that is a pointer to a list of Oids */
-#define COMPARE_OIDLIST_FIELD(fldname) \
-	do { \
-		if (!equalo(a->fldname, b->fldname)) \
-			return false; \
-	} while (0)
-
 /* Compare a field that is a pointer to a Bitmapset */
 #define COMPARE_BITMAPSET_FIELD(fldname) \
 	do { \
@@ -328,7 +316,7 @@ _equalSubLink(SubLink *a, SubLink *b)
 	COMPARE_SCALAR_FIELD(useOr);
 	COMPARE_NODE_FIELD(lefthand);
 	COMPARE_NODE_FIELD(operName);
-	COMPARE_OIDLIST_FIELD(operOids);
+	COMPARE_NODE_FIELD(operOids);
 	COMPARE_NODE_FIELD(subselect);
 
 	return true;
@@ -340,14 +328,14 @@ _equalSubPlan(SubPlan *a, SubPlan *b)
 	COMPARE_SCALAR_FIELD(subLinkType);
 	COMPARE_SCALAR_FIELD(useOr);
 	COMPARE_NODE_FIELD(exprs);
-	COMPARE_INTLIST_FIELD(paramIds);
+	COMPARE_NODE_FIELD(paramIds);
 	/* should compare plans, but have to settle for comparing plan IDs */
 	COMPARE_SCALAR_FIELD(plan_id);
 	COMPARE_NODE_FIELD(rtable);
 	COMPARE_SCALAR_FIELD(useHashTable);
 	COMPARE_SCALAR_FIELD(unknownEqFalse);
-	COMPARE_INTLIST_FIELD(setParam);
-	COMPARE_INTLIST_FIELD(parParam);
+	COMPARE_NODE_FIELD(setParam);
+	COMPARE_NODE_FIELD(parParam);
 	COMPARE_NODE_FIELD(args);
 
 	return true;
@@ -636,7 +624,7 @@ _equalQuery(Query *a, Query *b)
 	COMPARE_SCALAR_FIELD(hasSubLinks);
 	COMPARE_NODE_FIELD(rtable);
 	COMPARE_NODE_FIELD(jointree);
-	COMPARE_INTLIST_FIELD(rowMarks);
+	COMPARE_NODE_FIELD(rowMarks);
 	COMPARE_NODE_FIELD(targetList);
 	COMPARE_NODE_FIELD(groupClause);
 	COMPARE_NODE_FIELD(havingQual);
@@ -645,7 +633,7 @@ _equalQuery(Query *a, Query *b)
 	COMPARE_NODE_FIELD(limitOffset);
 	COMPARE_NODE_FIELD(limitCount);
 	COMPARE_NODE_FIELD(setOperations);
-	COMPARE_INTLIST_FIELD(resultRelations);
+	COMPARE_NODE_FIELD(resultRelations);
 	COMPARE_NODE_FIELD(in_info_list);
 	COMPARE_SCALAR_FIELD(hasJoinRTEs);
 
@@ -720,7 +708,7 @@ _equalSetOperationStmt(SetOperationStmt *a, SetOperationStmt *b)
 	COMPARE_SCALAR_FIELD(all);
 	COMPARE_NODE_FIELD(larg);
 	COMPARE_NODE_FIELD(rarg);
-	COMPARE_OIDLIST_FIELD(colTypes);
+	COMPARE_NODE_FIELD(colTypes);
 
 	return true;
 }
@@ -764,7 +752,7 @@ _equalGrantStmt(GrantStmt *a, GrantStmt *b)
 	COMPARE_SCALAR_FIELD(is_grant);
 	COMPARE_SCALAR_FIELD(objtype);
 	COMPARE_NODE_FIELD(objects);
-	COMPARE_INTLIST_FIELD(privileges);
+	COMPARE_NODE_FIELD(privileges);
 	COMPARE_NODE_FIELD(grantees);
 	COMPARE_SCALAR_FIELD(grant_option);
 	COMPARE_SCALAR_FIELD(behavior);
@@ -1389,7 +1377,7 @@ _equalPrepareStmt(PrepareStmt *a, PrepareStmt *b)
 {
 	COMPARE_STRING_FIELD(name);
 	COMPARE_NODE_FIELD(argtypes);
-	COMPARE_OIDLIST_FIELD(argtype_oids);
+	COMPARE_NODE_FIELD(argtype_oids);
 	COMPARE_NODE_FIELD(query);
 
 	return true;
@@ -1648,6 +1636,65 @@ _equalFkConstraint(FkConstraint *a, FkConstraint *b)
  * Stuff from pg_list.h
  */
 
+static bool
+_equalList(List *a, List *b)
+{
+	ListCell *item_a;
+	ListCell *item_b;
+
+	/*
+	 * Try to reject by simple scalar checks before grovelling through
+	 * all the list elements...
+	 */
+	COMPARE_SCALAR_FIELD(type);
+	COMPARE_SCALAR_FIELD(length);
+
+	/*
+	 * We place the switch outside the loop for the sake of
+	 * efficiency; this may not be worth doing...
+	 */
+	switch (a->type)
+	{
+		case T_List:
+			forboth(item_a, a, item_b, b)
+			{
+				if (!equal(lfirst(item_a), lfirst(item_b)))
+					return false;
+			}
+			break;
+		case T_IntList:
+			forboth(item_a, a, item_b, b)
+			{
+				if (lfirst_int(item_a) != lfirst_int(item_b))
+					return false;
+			}
+			break;
+		case T_OidList:
+			forboth(item_a, a, item_b, b)
+			{
+				if (lfirst_oid(item_a) != lfirst_oid(item_b))
+					return false;
+			}
+			break;
+		default:
+			elog(ERROR, "unrecognized list node type: %d",
+				 (int) a->type);
+			return false;		/* keep compiler quiet */
+	}
+
+	/*
+	 * If we got here, we should have run out of elements of both lists
+	 */
+	Assert(item_a == NULL);
+	Assert(item_b == NULL);
+
+	return true;
+}
+
+/*
+ * Stuff from value.h
+ */
+
 static bool
 _equalValue(Value *a, Value *b)
 {
@@ -1818,30 +1865,10 @@ equal(void *a, void *b)
 		case T_InClauseInfo:
 			retval = _equalInClauseInfo(a, b);
 			break;
-
-			/*
-			 * LIST NODES
-			 */
 		case T_List:
-			{
-				List	   *la = (List *) a;
-				List	   *lb = (List *) b;
-				List	   *l;
-
-				/*
-				 * Try to reject by length check before we grovel through
-				 * all the elements...
-				 */
-				if (length(la) != length(lb))
-					return false;
-				foreach(l, la)
-				{
-					if (!equal(lfirst(l), lfirst(lb)))
-						return false;
-					lb = lnext(lb);
-				}
-				retval = true;
-			}
+		case T_IntList:
+		case T_OidList:
+			retval = _equalList(a, b);
 			break;
 
 		case T_Integer:
diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c
index aeda02d17029a3dd43a0509ebde9c36f0a0af725..6fd7b064a6b531be48da7bd321556447b169966c 100644
--- a/src/backend/nodes/list.c
+++ b/src/backend/nodes/list.c
@@ -9,700 +9,1160 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/list.c,v 1.56 2004/01/07 18:43:36 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/list.c,v 1.57 2004/05/26 04:41:19 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
+#define DISABLE_LIST_COMPAT
+
 #include "postgres.h"
+#include "nodes/pg_list.h"
 
-#include "nodes/parsenodes.h"
+/*
+ * Routines to simplify writing assertions about the type of a list; a
+ * NIL list is considered to be an empty list of any type.
+ */
+#define IsPointerList(l)		((l) == NIL || IsA((l), List))
+#define IsIntegerList(l)		((l) == NIL || IsA((l), IntList))
+#define IsOidList(l)			((l) == NIL || IsA((l), OidList))
 
+#ifdef USE_ASSERT_CHECKING
 /*
- *	lcons
- *
- *	Add obj to the front of list, or make a new list if 'list' is NIL
+ * Check that the specified List is valid (so far as we can tell).
  */
-List *
-lcons(void *obj, List *list)
+static void
+check_list_invariants(List *list)
 {
-	List	   *l = makeNode(List);
+	if (list == NIL)
+		return;
+
+	Assert(list->length > 0);
+	Assert(list->head != NULL);
+	Assert(list->tail != NULL);
+
+	Assert(list->type == T_List ||
+		   list->type == T_IntList ||
+		   list->type == T_OidList);
+
+	if (list->length == 1)
+		Assert(list->head == list->tail);
+	if (list->length == 2)
+		Assert(list->head->next == list->tail);
+	Assert(list->tail->next == NULL);
+}
+#else
+#define check_list_invariants(l)
+#endif /* USE_ASSERT_CHECKING */
+
+/*
+ * Return a freshly allocated List. Since empty non-NIL lists are
+ * invalid, new_list() also allocates the head cell of the new list:
+ * the caller should be sure to fill in that cell's data.
+ */
+static List *
+new_list(NodeTag type)
+{
+	List		*new_list;
+	ListCell	*new_head;
+
+	new_head = (ListCell *) palloc(sizeof(*new_head));
+	new_head->next = NULL;
+	/* new_head->data is left undefined! */
 
-	lfirst(l) = obj;
-	lnext(l) = list;
-	return l;
+	new_list = (List *) palloc(sizeof(*new_list));
+	new_list->type = type;
+	new_list->length = 1;
+	new_list->head = new_head;
+	new_list->tail = new_head;
+
+	return new_list;
 }
 
 /*
- *	lconsi
+ * Allocate a new cell and make it the head of the specified
+ * list. Assumes the list it is passed is non-NIL.
  *
- *	Same as lcons, but for integer data
+ * The data in the new head cell is undefined; the caller should be
+ * sure to fill it in
  */
-List *
-lconsi(int datum, List *list)
+static void
+new_head_cell(List *list)
 {
-	List	   *l = makeNode(List);
+	ListCell *new_head;
+
+	new_head = (ListCell *) palloc(sizeof(*new_head));
+	new_head->next = list->head;
 
-	lfirsti(l) = datum;
-	lnext(l) = list;
-	return l;
+	list->head = new_head;
+	list->length++;
 }
 
 /*
- *	lconso
+ * Allocate a new cell and make it the tail of the specified
+ * list. Assumes the list it is passed is non-NIL.
  *
- *	Same as lcons, but for Oid data
+ * The data in the new tail cell is undefined; the caller should be
+ * sure to fill it in
  */
-List *
-lconso(Oid datum, List *list)
+static void
+new_tail_cell(List *list)
 {
-	List	   *l = makeNode(List);
+	ListCell *new_tail;
+
+	new_tail = (ListCell *) palloc(sizeof(*new_tail));
+	new_tail->next = NULL;
 
-	lfirsto(l) = datum;
-	lnext(l) = list;
-	return l;
+	list->tail->next = new_tail;
+	list->tail = new_tail;
+	list->length++;
 }
 
 /*
- *	lappend
- *
- *	Add obj to the end of list, or make a new list if 'list' is NIL
- *
- * MORE EXPENSIVE THAN lcons
+ * Append a pointer to the list. A pointer to the modified list is
+ * returned. Note that this function may or may not destructively
+ * modify the list; callers should always use this function's return
+ * value, rather than continuing to use the pointer passed as the
+ * first argument.
  */
 List *
 lappend(List *list, void *datum)
 {
-	return nconc(list, makeList1(datum));
+	Assert(IsPointerList(list));
+
+	if (list == NIL)
+		list = new_list(T_List);
+	else
+		new_tail_cell(list);
+
+	lfirst(list->tail) = datum;
+	check_list_invariants(list);
+	return list;
 }
 
 /*
- *	lappendi
- *
- *	Same as lappend, but for integers
+ * Append an integer to the specified list. See lappend()
  */
-List *
-lappendi(List *list, int datum)
+List * 
+lappend_int(List *list, int datum)
 {
-	return nconc(list, makeListi1(datum));
+	Assert(IsIntegerList(list));
+
+	if (list == NIL)
+		list = new_list(T_IntList);
+	else
+		new_tail_cell(list);
+
+	lfirst_int(list->tail) = datum;
+	check_list_invariants(list);
+	return list;
 }
 
 /*
- *	lappendo
- *
- *	Same as lappend, but for Oids
+ * Append an OID to the specified list. See lappend()
  */
-List *
-lappendo(List *list, Oid datum)
+List * 
+lappend_oid(List *list, Oid datum)
 {
-	return nconc(list, makeListo1(datum));
+	Assert(IsOidList(list));
+
+	if (list == NIL)
+		list = new_list(T_OidList);
+	else
+		new_tail_cell(list);
+
+	lfirst_oid(list->tail) = datum;
+	check_list_invariants(list);
+	return list;
 }
 
 /*
- *	nconc
- *
- *	Concat l2 on to the end of l1
- *
- * NB: l1 is destructively changed!  Use nconc(listCopy(l1), l2)
- * if you need to make a merged list without touching the original lists.
+ * Add a new cell to the list, in the position after 'prev_cell'. The
+ * data in the cell is left undefined, and must be filled in by the
+ * caller. 'list' is assumed to be non-NIL, and 'prev_cell' is assumed
+ * to be non-NULL and a member of 'list'.
  */
-List *
-nconc(List *l1, List *l2)
+static ListCell *
+add_new_cell(List *list, ListCell *prev_cell)
 {
-	List	   *temp;
+	ListCell *new_cell;
 
-	if (l1 == NIL)
-		return l2;
-	if (l2 == NIL)
-		return l1;
-	if (l1 == l2)
-		elog(ERROR, "cannot nconc a list to itself");
+	new_cell = (ListCell *) palloc(sizeof(*new_cell));
+	/* new_cell->data is left undefined! */
+	new_cell->next = prev_cell->next;
+	prev_cell->next = new_cell;
 
-	for (temp = l1; lnext(temp) != NIL; temp = lnext(temp))
-		;
+	if (list->tail == prev_cell)
+		list->tail = new_cell;
+
+	list->length++;
 
-	lnext(temp) = l2;
-	return l1;					/* list1 is now list1+list2  */
+	return new_cell;
 }
 
 /*
- * FastAppend - append to a FastList.
+ * Add a new cell to the specified list (which must be non-NIL);
+ * it will be placed after the list cell 'prev' (which must be
+ * non-NULL and a member of 'list'). The data placed in the new cell
+ * is 'datum'. The newly-constructed cell is returned.
+ */
+ListCell *
+lappend_cell(List *list, ListCell *prev, void *datum)
+{
+	ListCell *new_cell;
+
+	Assert(IsPointerList(list));
+
+	new_cell = add_new_cell(list, prev);
+	lfirst(new_cell) = datum;
+	check_list_invariants(list);
+	return new_cell;
+}
+
+ListCell *
+lappend_cell_int(List *list, ListCell *prev, int datum)
+{
+	ListCell *new_cell;
+
+	Assert(IsIntegerList(list));
+
+	new_cell = add_new_cell(list, prev);
+	lfirst_int(new_cell) = datum;
+	check_list_invariants(list);
+	return new_cell;
+}
+
+ListCell *
+lappend_cell_oid(List *list, ListCell *prev, Oid datum)
+{
+	ListCell *new_cell;
+
+	Assert(IsOidList(list));
+
+	new_cell = add_new_cell(list, prev);
+	lfirst_oid(new_cell) = datum;
+	check_list_invariants(list);
+	return new_cell;
+}
+
+/*
+ * Prepend a new element to the list. A pointer to the modified list
+ * is returned. Note that this function may or may not destructively
+ * modify the list; callers should always use this function's return
+ * value, rather than continuing to use the pointer passed as the
+ * second argument.
  *
- * For long lists this is significantly faster than repeated lappend's,
- * since we avoid having to chase down the list again each time.
+ * Caution: before Postgres 7.5, the original List was unmodified and
+ * could be considered to retain its separate identity.  This is no longer
+ * the case.
  */
-void
-FastAppend(FastList *fl, void *datum)
+List *
+lcons(void *datum, List *list)
 {
-	List	   *cell = makeList1(datum);
+	Assert(IsPointerList(list));
 
-	if (fl->tail)
-	{
-		lnext(fl->tail) = cell;
-		fl->tail = cell;
-	}
+	if (list == NIL)
+		list = new_list(T_List);
 	else
-	{
-		/* First cell of list */
-		Assert(fl->head == NIL);
-		fl->head = fl->tail = cell;
-	}
+		new_head_cell(list);
+
+	lfirst(list->head) = datum;
+	check_list_invariants(list);
+	return list;
 }
 
 /*
- * FastAppendi - same for integers
+ * Prepend an integer to the list. See lcons()
  */
-void
-FastAppendi(FastList *fl, int datum)
+List *
+lcons_int(int datum, List *list)
 {
-	List	   *cell = makeListi1(datum);
+	Assert(IsIntegerList(list));
 
-	if (fl->tail)
-	{
-		lnext(fl->tail) = cell;
-		fl->tail = cell;
-	}
+	if (list == NIL)
+		list = new_list(T_IntList);
 	else
-	{
-		/* First cell of list */
-		Assert(fl->head == NIL);
-		fl->head = fl->tail = cell;
-	}
+		new_head_cell(list);
+
+	lfirst_int(list->head) = datum;
+	check_list_invariants(list);
+	return list;
 }
 
 /*
- * FastAppendo - same for Oids
+ * Prepend an OID to the list. See lcons()
  */
-void
-FastAppendo(FastList *fl, Oid datum)
+List * 
+lcons_oid(Oid datum, List *list)
 {
-	List	   *cell = makeListo1(datum);
+	Assert(IsOidList(list));
 
-	if (fl->tail)
-	{
-		lnext(fl->tail) = cell;
-		fl->tail = cell;
-	}
+	if (list == NIL)
+		list = new_list(T_OidList);
 	else
-	{
-		/* First cell of list */
-		Assert(fl->head == NIL);
-		fl->head = fl->tail = cell;
-	}
+		new_head_cell(list);
+
+	lfirst_oid(list->head) = datum;
+	check_list_invariants(list);
+	return list;
 }
 
 /*
- * FastConc - nconc() for FastList building
+ * Concatenate list2 to the end of list1, and return list1. list1 is
+ * destructively changed. Callers should be sure to use the return
+ * value as the new pointer to the concatenated list: the 'list1'
+ * input pointer may or may not be the same as the returned pointer.
  *
- * Note that the cells of the second argument are absorbed into the FastList.
+ * The nodes in list2 are merely appended to the end of list1 in-place
+ * (i.e. they aren't copied; the two lists will share some of the same
+ * storage). Therefore, invoking list_free() on list2 will also
+ * invalidate a portion of list1.
  */
-void
-FastConc(FastList *fl, List *cells)
+List *
+list_concat(List *list1, List *list2)
 {
-	if (cells == NIL)
-		return;					/* nothing to do */
-	if (fl->tail)
-		lnext(fl->tail) = cells;
-	else
-	{
-		/* First cell of list */
-		Assert(fl->head == NIL);
-		fl->head = cells;
-	}
-	while (lnext(cells) != NIL)
-		cells = lnext(cells);
-	fl->tail = cells;
+	if (list1 == NIL)
+		return list2;
+	if (list2 == NIL)
+		return list1;
+	if (list1 == list2)
+		elog(ERROR, "cannot list_concat() a list to itself");
+
+	Assert(list1->type == list2->type);
+
+	list1->length += list2->length;
+	list1->tail->next = list2->head;
+	list1->tail = list2->tail;
+
+	check_list_invariants(list1);
+	return list1;
 }
 
 /*
- * FastConcFast - nconc() for FastList building
+ * Truncate 'list' to contain no more than 'new_size' elements. This
+ * modifies the list in-place! Despite this, callers should use the
+ * pointer returned by this function to refer to the newly truncated
+ * list -- it may or may not be the same as the pointer that was
+ * passed.
  *
- * Note that the cells of the second argument are absorbed into the first.
+ * Note that any cells removed by list_truncate() are NOT pfree'd.
  */
-void
-FastConcFast(FastList *fl, FastList *fl2)
+List *
+list_truncate(List *list, int new_size)
 {
-	if (fl2->head == NIL)
-		return;					/* nothing to do */
-	if (fl->tail)
-		lnext(fl->tail) = fl2->head;
-	else
+	ListCell	*cell;
+	int			 n;
+
+	if (new_size <= 0)
+		return NIL;		/* truncate to zero length */
+
+	/* If asked to effectively extend the list, do nothing */
+	if (new_size >= list_length(list))
+		return list;
+
+	n = 1;
+	foreach (cell, list)
 	{
-		/* First cell of list */
-		Assert(fl->head == NIL);
-		fl->head = fl2->head;
+		if (n == new_size)
+		{
+			cell->next = NULL;
+			list->tail = cell;
+			list->length = new_size;
+			check_list_invariants(list);
+			return list;
+		}
+		n++;
 	}
-	fl->tail = fl2->tail;
+
+	/* keep the compiler quiet; never reached */
+	Assert(false);
+	return list;
 }
 
 /*
- *	nth
- *
- *	Get the n'th element of the list.  First element is 0th.
+ * Locate the n'th cell (counting from 0) of the list.  It is an assertion
+ * error if there isn't one.
+ */
+static ListCell *
+list_nth_cell(List *list, int n)
+{
+	ListCell *match;
+
+	Assert(list != NIL);
+	Assert(n >= 0);
+	Assert(n < list->length);
+	check_list_invariants(list);
+
+	/* Does the caller actually mean to fetch the tail? */
+	if (n == list->length - 1)
+		return list->tail;
+
+	for (match = list->head; n-- > 0; match = match->next)
+		;
+
+	return match;
+}
+
+/*
+ * Return the data value contained in the n'th element of the
+ * specified list. (List elements begin at 0.)
  */
 void *
-nth(int n, List *l)
+list_nth(List *list, int n)
 {
-	/* XXX assume list is long enough */
-	while (n-- > 0)
-		l = lnext(l);
-	return lfirst(l);
+	Assert(IsPointerList(list));
+	return lfirst(list_nth_cell(list, n));
 }
 
 /*
- *	length
- *
- *	Get the length of l
+ * Return the integer value contained in the n'th element of the
+ * specified list.
  */
 int
-length(List *l)
+list_nth_int(List *list, int n)
 {
-	int			i = 0;
-
-	while (l != NIL)
-	{
-		l = lnext(l);
-		i++;
-	}
-	return i;
+	Assert(IsIntegerList(list));
+	return lfirst_int(list_nth_cell(list, n));
 }
 
 /*
- *	llast
- *
- *	Get the last element of l ... error if empty list
+ * Return the OID value contained in the n'th element of the specified
+ * list.
  */
-void *
-llast(List *l)
+Oid
+list_nth_oid(List *list, int n)
 {
-	if (l == NIL)
-		elog(ERROR, "empty list does not have a last item");
-	while (lnext(l) != NIL)
-		l = lnext(l);
-	return lfirst(l);
+	Assert(IsOidList(list));
+	return lfirst_oid(list_nth_cell(list, n));
 }
 
 /*
- *	llastnode
- *
- *	Get the last node of l ... NIL if empty list
+ * Return true iff 'datum' is a member of the list. Equality is
+ * determined via equal(), so callers should ensure that they pass a
+ * Node as 'datum'.
  */
-List *
-llastnode(List *l)
+bool
+list_member(List *list, void *datum)
 {
-	if (l == NIL)
-		return NIL;
-	while (lnext(l) != NIL)
-		l = lnext(l);
-	return l;
+	ListCell *cell;
+
+	Assert(IsPointerList(list));
+	check_list_invariants(list);
+
+	foreach (cell, list)
+	{
+		if (equal(lfirst(cell), datum))
+			return true;
+	}
+
+	return false;
 }
 
 /*
- *	freeList
- *
- *	Free the List nodes of a list
- *	The pointed-to nodes, if any, are NOT freed.
- *	This works for integer and Oid lists too.
+ * Return true iff 'datum' is a member of the list. Equality is
+ * determined by using simple pointer comparison.
  */
-void
-freeList(List *list)
+bool
+list_member_ptr(List *list, void *datum)
 {
-	while (list != NIL)
-	{
-		List	   *l = list;
+	ListCell *cell;
 
-		list = lnext(list);
-		pfree(l);
+	Assert(IsPointerList(list));
+	check_list_invariants(list);
+
+	foreach (cell, list)
+	{
+		if (lfirst(cell) == datum)
+			return true;
 	}
+
+	return false;
 }
 
 /*
- * equali
- *	  compares two lists of integers
+ * Return true iff the integer 'datum' is a member of the list.
  */
 bool
-equali(List *list1, List *list2)
+list_member_int(List *list, int datum)
 {
-	List	   *l;
+	ListCell *cell;
+
+	Assert(IsIntegerList(list));
+	check_list_invariants(list);
 
-	foreach(l, list1)
+	foreach (cell, list)
 	{
-		if (list2 == NIL)
-			return false;
-		if (lfirsti(l) != lfirsti(list2))
-			return false;
-		list2 = lnext(list2);
+		if (lfirst_int(cell) == datum)
+			return true;
 	}
-	if (list2 != NIL)
-		return false;
-	return true;
+
+	return false;
 }
 
 /*
- * equalo
- *	  compares two lists of Oids
+ * Return true iff the OID 'datum' is a member of the list.
  */
 bool
-equalo(List *list1, List *list2)
+list_member_oid(List *list, Oid datum)
 {
-	List	   *l;
+	ListCell *cell;
+
+	Assert(IsOidList(list));
+	check_list_invariants(list);
 
-	foreach(l, list1)
+	foreach (cell, list)
 	{
-		if (list2 == NIL)
-			return false;
-		if (lfirsto(l) != lfirsto(list2))
-			return false;
-		list2 = lnext(list2);
+		if (lfirst_oid(cell) == datum)
+			return true;
 	}
-	if (list2 != NIL)
-		return false;
-	return true;
+
+	return false;
 }
 
 /*
- * Generate the union of two lists,
- * ie, l1 plus all members of l2 that are not already in l1.
- *
- * NOTE: if there are duplicates in l1 they will still be duplicate in the
- * result; but duplicates in l2 are discarded.
+ * Delete 'cell' from 'list'; 'prev' is the previous element to 'cell'
+ * in 'list', if any (i.e. prev == NULL iff list->head == cell)
  *
- * The result is a fresh List, but it points to the same member nodes
- * as were in the inputs.
+ * The cell is pfree'd, as is the List header if this was the last member.
  */
 List *
-set_union(List *l1, List *l2)
+list_delete_cell(List *list, ListCell *cell, ListCell *prev)
 {
-	List	   *retval = listCopy(l1);
-	List	   *i;
+	check_list_invariants(list);
+	Assert(prev != NULL ? lnext(prev) == cell : list_head(list) == cell);
+
+	/*
+	 * If we're about to delete the last node from the list, free the
+	 * whole list instead and return NIL, which is the only valid
+	 * representation of a zero-length list.
+	 */
+	if (list->length == 1)
+	{
+		list_free(list);
+		return NIL;
+	}
 
-	foreach(i, l2)
+	/*
+	 * Otherwise, adjust the necessary list links, deallocate the
+	 * particular node we have just removed, and return the list we
+	 * were given.
+	 */
+	list->length--;
+
+	if (prev)
+		prev->next = cell->next;
+	else
+		list->head = cell->next;
+
+	if (list->tail == cell)
+		list->tail = prev;
+
+	pfree(cell);
+	return list;
+}
+
+/*
+ * Delete the first cell in list that matches datum, if any.
+ * Equality is determined via equal().
+ */
+List *
+list_delete(List *list, void *datum)
+{
+	ListCell	*cell;
+	ListCell	*prev;
+
+	Assert(IsPointerList(list));
+	check_list_invariants(list);
+
+	prev = NULL;
+	foreach (cell, list)
 	{
-		if (!member(lfirst(i), retval))
-			retval = lappend(retval, lfirst(i));
+		if (equal(lfirst(cell), datum))
+			return list_delete_cell(list, cell, prev);
+
+		prev = cell;
 	}
-	return retval;
+
+	/* Didn't find a match: return the list unmodified */
+	return list;
 }
 
-/* set_union for Oid lists */
+/* As above, but use simple pointer equality */
 List *
-set_uniono(List *l1, List *l2)
+list_delete_ptr(List *list, void *datum)
 {
-	List	   *retval = listCopy(l1);
-	List	   *i;
+	ListCell	*cell;
+	ListCell	*prev;
 
-	foreach(i, l2)
+	Assert(IsPointerList(list));
+	check_list_invariants(list);
+
+	prev = NULL;
+	foreach (cell, list)
 	{
-		if (!oidMember(lfirsto(i), retval))
-			retval = lappendo(retval, lfirsto(i));
+		if (lfirst(cell) == datum)
+			return list_delete_cell(list, cell, prev);
+
+		prev = cell;
 	}
-	return retval;
+
+	/* Didn't find a match: return the list unmodified */
+	return list;
 }
 
-/* set_union when pointer-equality comparison is sufficient */
+/* As above, but for integers */
 List *
-set_ptrUnion(List *l1, List *l2)
+list_delete_int(List *list, int datum)
 {
-	List	   *retval = listCopy(l1);
-	List	   *i;
+	ListCell	*cell;
+	ListCell	*prev;
+
+	Assert(IsIntegerList(list));
+	check_list_invariants(list);
 
-	foreach(i, l2)
+	prev = NULL;
+	foreach (cell, list)
 	{
-		if (!ptrMember(lfirst(i), retval))
-			retval = lappend(retval, lfirst(i));
+		if (lfirst_int(cell) == datum)
+			return list_delete_cell(list, cell, prev);
+
+		prev = cell;
 	}
-	return retval;
+
+	/* Didn't find a match: return the list unmodified */
+	return list;
+}
+
+/* As above, but for OIDs */
+List *
+list_delete_oid(List *list, Oid datum)
+{
+	ListCell	*cell;
+	ListCell	*prev;
+
+	Assert(IsOidList(list));
+	check_list_invariants(list);
+
+	prev = NULL;
+	foreach (cell, list)
+	{
+		if (lfirst_oid(cell) == datum)
+			return list_delete_cell(list, cell, prev);
+
+		prev = cell;
+	}
+
+	/* Didn't find a match: return the list unmodified */
+	return list;
 }
 
 /*
- * Generate the intersection of two lists,
- * ie, all members of both l1 and l2.
- *
- * NOTE: if there are duplicates in l1 they will still be duplicate in the
- * result; but duplicates in l2 are discarded.
+ * Delete the first element of the list.
  *
- * The result is a fresh List, but it points to the same member nodes
- * as were in the inputs.
+ * This is useful to replace the Lisp-y code "list = lnext(list);" in cases
+ * where the intent is to alter the list rather than just traverse it.
+ * Beware that the removed cell is freed, whereas the lnext() coding leaves
+ * the original list head intact if there's another pointer to it.
  */
-#ifdef NOT_USED
 List *
-set_intersect(List *l1, List *l2)
+list_delete_first(List *list)
 {
-	List	   *retval = NIL;
-	List	   *i;
+	check_list_invariants(list);
 
-	foreach(i, l1)
-	{
-		if (member(lfirst(i), l2))
-			retval = lappend(retval, lfirst(i));
-	}
-	return retval;
+	if (list == NIL)
+		return NIL;				/* would an error be better? */
+
+	return list_delete_cell(list, list_head(list), NULL);
 }
-#endif
 
 /*
- * member()
- *	nondestructive, returns t iff l1 is a member of the list l2
+ * Generate the union of two lists. This is calculated by copying
+ * list1 via list_copy(), then adding to it all the members of list2
+ * that aren't already in list1.
+ *
+ * Whether an element is already a member of the list is determined
+ * via equal().
+ *
+ * The returned list is newly-allocated, although the content of the
+ * cells is the same (i.e. any pointed-to objects are not copied).
+ *
+ * NB: Bizarrely, this function will NOT remove any duplicates that
+ * are present in list1 (so it is not really a union at all!). Also,
+ * this function could probably be implemented a lot faster if it is a
+ * performance bottleneck.
  */
-bool
-member(void *l1, List *l2)
+List *
+list_union(List *list1, List *list2)
 {
-	List	   *i;
+	List		*result;
+	ListCell	*cell;
+
+	Assert(IsPointerList(list1));
+	Assert(IsPointerList(list2));
 
-	foreach(i, l2)
+	result = list_copy(list1);
+	foreach(cell, list2)
 	{
-		if (equal((Node *) l1, (Node *) lfirst(i)))
-			return true;
+		if (!list_member(result, lfirst(cell)))
+			result = lappend(result, lfirst(cell));
 	}
-	return false;
+
+	check_list_invariants(result);
+	return result;
 }
 
 /*
- * like member(), but use when pointer-equality comparison is sufficient
+ * This variant of list_union() determines duplicates via simple
+ * pointer comparison.
  */
-bool
-ptrMember(void *l1, List *l2)
+List *
+list_union_ptr(List *list1, List *list2)
 {
-	List	   *i;
+	List		*result;
+	ListCell	*cell;
 
-	foreach(i, l2)
+	Assert(IsPointerList(list1));
+	Assert(IsPointerList(list2));
+
+	result = list_copy(list1);
+	foreach(cell, list2)
 	{
-		if (l1 == lfirst(i))
-			return true;
+		if (!list_member_ptr(result, lfirst(cell)))
+			result = lappend(result, lfirst(cell));
 	}
-	return false;
+
+	check_list_invariants(result);
+	return result;
 }
 
 /*
- * membership test for integer lists
+ * This variant of list_union() operates upon lists of integers.
  */
-bool
-intMember(int l1, List *l2)
+List *
+list_union_int(List *list1, List *list2)
 {
-	List	   *i;
+	List		*result;
+	ListCell	*cell;
+
+	Assert(IsIntegerList(list1));
+	Assert(IsIntegerList(list2));
 
-	foreach(i, l2)
+	result = list_copy(list1);
+	foreach(cell, list2)
 	{
-		if (l1 == lfirsti(i))
-			return true;
+		if (!list_member_int(result, lfirst_int(cell)))
+			result = lappend_int(result, lfirst_int(cell));
 	}
-	return false;
+
+	check_list_invariants(result);
+	return result;
 }
 
 /*
- * membership test for Oid lists
+ * This variant of list_union() operates upon lists of OIDs.
  */
-bool
-oidMember(Oid l1, List *l2)
+List *
+list_union_oid(List *list1, List *list2)
 {
-	List	   *i;
+	List		*result;
+	ListCell	*cell;
+
+	Assert(IsOidList(list1));
+	Assert(IsOidList(list2));
 
-	foreach(i, l2)
+	result = list_copy(list1);
+	foreach(cell, list2)
 	{
-		if (l1 == lfirsto(i))
-			return true;
+		if (!list_member_oid(result, lfirst_oid(cell)))
+			result = lappend_oid(result, lfirst_oid(cell));
 	}
-	return false;
+
+	check_list_invariants(result);
+	return result;
 }
 
 /*
- * lremove
- *	  Removes 'elem' from the linked list (destructively changing the list!).
- *	  (If there is more than one equal list member, the first is removed.)
+ * Return a list that contains all the cells in list1 that are not in
+ * list2. The returned list is freshly allocated via palloc(), but the
+ * cells themselves point to the same objects as the cells of the
+ * input lists.
  *
- *	  This version matches 'elem' using simple pointer comparison.
- *	  See also LispRemove.
+ * This variant works on lists of pointers, and determines list
+ * membership via equal()
  */
 List *
-lremove(void *elem, List *list)
+list_difference(List *list1, List *list2)
 {
-	List	   *l;
-	List	   *prev = NIL;
-	List	   *result = list;
+	ListCell	*cell;
+	List		*result = NIL;
 
-	foreach(l, list)
-	{
-		if (elem == lfirst(l))
-			break;
-		prev = l;
-	}
-	if (l != NIL)
+	Assert(IsPointerList(list1));
+	Assert(IsPointerList(list2));
+
+	if (list2 == NIL)
+		return list_copy(list1);
+
+	foreach (cell, list1)
 	{
-		if (prev == NIL)
-			result = lnext(l);
-		else
-			lnext(prev) = lnext(l);
-		pfree(l);
+		if (!list_member(list2, lfirst(cell)))
+			result = lappend(result, lfirst(cell));
 	}
+
+	check_list_invariants(result);
 	return result;
 }
 
 /*
- *	LispRemove
- *	  Removes 'elem' from the linked list (destructively changing the list!).
- *	  (If there is more than one equal list member, the first is removed.)
- *
- *	  This version matches 'elem' using equal().
- *	  See also lremove.
+ * This variant of list_difference() determines list membership via
+ * simple pointer equality.
  */
 List *
-LispRemove(void *elem, List *list)
+list_difference_ptr(List *list1, List *list2)
 {
-	List	   *l;
-	List	   *prev = NIL;
-	List	   *result = list;
+	ListCell	*cell;
+	List		*result = NIL;
 
-	foreach(l, list)
-	{
-		if (equal(elem, lfirst(l)))
-			break;
-		prev = l;
-	}
-	if (l != NIL)
+	Assert(IsPointerList(list1));
+	Assert(IsPointerList(list2));
+
+	if (list2 == NIL)
+		return list_copy(list1);
+
+	foreach (cell, list1)
 	{
-		if (prev == NIL)
-			result = lnext(l);
-		else
-			lnext(prev) = lnext(l);
-		pfree(l);
+		if (!list_member_ptr(list2, lfirst(cell)))
+			result = lappend(result, lfirst(cell));
 	}
+
+	check_list_invariants(result);
 	return result;
 }
 
 /*
- *	lremovei
- *		lremove() for integer lists.
+ * This variant of list_difference() operates upon lists of integers.
  */
 List *
-lremovei(int elem, List *list)
+list_difference_int(List *list1, List *list2)
 {
-	List	   *l;
-	List	   *prev = NIL;
-	List	   *result = list;
+	ListCell	*cell;
+	List		*result = NIL;
 
-	foreach(l, list)
-	{
-		if (elem == lfirsti(l))
-			break;
-		prev = l;
-	}
-	if (l != NIL)
+	Assert(IsIntegerList(list1));
+	Assert(IsIntegerList(list2));
+
+	if (list2 == NIL)
+		return list_copy(list1);
+
+	foreach (cell, list1)
 	{
-		if (prev == NIL)
-			result = lnext(l);
-		else
-			lnext(prev) = lnext(l);
-		pfree(l);
+		if (!list_member_int(list2, lfirst_int(cell)))
+			result = lappend_int(result, lfirst_int(cell));
 	}
+
+	check_list_invariants(result);
 	return result;
 }
 
 /*
- * ltruncate
- *		Truncate a list to n elements.
- *		Does nothing if n >= length(list).
- *		NB: the list is modified in-place!
+ * This variant of list_difference() operates upon lists of OIDs.
  */
 List *
-ltruncate(int n, List *list)
+list_difference_oid(List *list1, List *list2)
 {
-	List	   *ptr;
+	ListCell	*cell;
+	List		*result = NIL;
 
-	if (n <= 0)
-		return NIL;				/* truncate to zero length */
+	Assert(IsOidList(list1));
+	Assert(IsOidList(list2));
 
-	foreach(ptr, list)
+	if (list2 == NIL)
+		return list_copy(list1);
+
+	foreach (cell, list1)
 	{
-		if (--n == 0)
-		{
-			lnext(ptr) = NIL;
-			break;
-		}
+		if (!list_member_oid(list2, lfirst_oid(cell)))
+			result = lappend_oid(result, lfirst_oid(cell));
 	}
-	return list;
+
+	check_list_invariants(result);
+	return result;
+}
+
+/* Free all storage in a list, and optionally the pointed-to elements */
+static void
+list_free_private(List *list, bool deep)
+{
+	ListCell	*cell;
+
+	check_list_invariants(list);
+
+	cell = list_head(list);
+	while (cell != NULL)
+	{
+		ListCell *tmp = cell;
+
+		cell = lnext(cell);
+		if (deep)
+			pfree(lfirst(tmp));
+		pfree(tmp);
+	}
+
+	if (list)
+		pfree(list);
 }
 
 /*
- *	set_difference
+ * Free all the cells of the list, as well as the list itself. Any
+ * objects that are pointed-to by the cells of the list are NOT
+ * free'd.
  *
- *	Return l1 without the elements in l2.
+ * On return, the argument to this function has been freed, so the
+ * caller would be wise to set it to NIL for safety's sake.
+ */
+void
+list_free(List *list)
+{
+	list_free_private(list, false);
+}
+
+/*
+ * Free all the cells of the list, the list itself, and all the
+ * objects pointed-to by the cells of the list (each element in the
+ * list must contain a pointer to a palloc()'d region of memory!)
  *
- * The result is a fresh List, but it points to the same member nodes
- * as were in l1.
+ * On return, the argument to this function has been freed, so the
+ * caller would be wise to set it to NIL for safety's sake.
+ */
+void
+list_free_deep(List *list)
+{
+	/*
+	 * A "deep" free operation only makes sense on a list of pointers.
+	 */
+	Assert(IsPointerList(list));
+	list_free_private(list, true);
+}
+
+/*
+ * Return a shallow copy of the specified list.
  */
 List *
-set_difference(List *l1, List *l2)
+list_copy(List *oldlist)
 {
-	List	   *result = NIL;
-	List	   *i;
+	List		*newlist;
+	ListCell	*newlist_prev;
+	ListCell	*oldlist_cur;
+
+	if (oldlist == NIL)
+		return NIL;
 
-	if (l2 == NIL)
-		return listCopy(l1);	/* slightly faster path for empty l2 */
+	newlist = new_list(oldlist->type);
+	newlist->length = oldlist->length;
 
-	foreach(i, l1)
+	/*
+	 * Copy over the data in the first cell; new_list() has already
+	 * allocated the head cell itself
+	 */
+	newlist->head->data = oldlist->head->data;
+
+	newlist_prev = newlist->head;
+	oldlist_cur = oldlist->head->next;
+	while (oldlist_cur)
 	{
-		if (!member(lfirst(i), l2))
-			result = lappend(result, lfirst(i));
+		ListCell *newlist_cur;
+
+		newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur));
+		newlist_cur->data = oldlist_cur->data;
+		newlist_prev->next = newlist_cur;
+
+		newlist_prev = newlist_cur;
+		oldlist_cur = oldlist_cur->next;
 	}
-	return result;
+
+	newlist_prev->next = NULL;
+	newlist->tail = newlist_prev;
+
+	check_list_invariants(newlist);
+	return newlist;
 }
 
 /*
- *	set_differenceo
- *
- *	Same as set_difference, but for Oid lists
+ * Return a shallow copy of the specified list, without the first N elements.
  */
 List *
-set_differenceo(List *l1, List *l2)
+list_copy_tail(List *oldlist, int nskip)
 {
-	List	   *result = NIL;
-	List	   *i;
+	List		*newlist;
+	ListCell	*newlist_prev;
+	ListCell	*oldlist_cur;
+
+	if (nskip < 0)
+		nskip = 0;				/* would it be better to elog? */
 
-	if (l2 == NIL)
-		return listCopy(l1);	/* slightly faster path for empty l2 */
+	if (oldlist == NIL || nskip >= oldlist->length)
+		return NIL;
 
-	foreach(i, l1)
+	newlist = new_list(oldlist->type);
+	newlist->length = oldlist->length - nskip;
+
+	/*
+	 * Skip over the unwanted elements.
+	 */
+	oldlist_cur = oldlist->head;
+	while (nskip-- > 0)
+		oldlist_cur = oldlist_cur->next;
+
+	/*
+	 * Copy over the data in the first remaining cell; new_list() has already
+	 * allocated the head cell itself
+	 */
+	newlist->head->data = oldlist_cur->data;
+
+	newlist_prev = newlist->head;
+	oldlist_cur = oldlist_cur->next;
+	while (oldlist_cur)
 	{
-		if (!oidMember(lfirsto(i), l2))
-			result = lappendo(result, lfirsto(i));
+		ListCell *newlist_cur;
+
+		newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur));
+		newlist_cur->data = oldlist_cur->data;
+		newlist_prev->next = newlist_cur;
+
+		newlist_prev = newlist_cur;
+		oldlist_cur = oldlist_cur->next;
 	}
-	return result;
+
+	newlist_prev->next = NULL;
+	newlist->tail = newlist_prev;
+
+	check_list_invariants(newlist);
+	return newlist;
 }
 
 /*
- *	set_ptrDifference
+ * When using non-GCC compilers, we can't define these as inline
+ * functions in pg_list.h, so they are defined here.
  *
- *	Same as set_difference, when pointer-equality comparison is sufficient
+ * TODO: investigate supporting inlining for some non-GCC compilers.
  */
-List *
-set_ptrDifference(List *l1, List *l2)
+#ifndef __GNUC__
+
+ListCell *
+list_head(List *l)
 {
-	List	   *result = NIL;
-	List	   *i;
+	return l ? l->head : NULL;
+}
 
-	if (l2 == NIL)
-		return listCopy(l1);	/* slightly faster path for empty l2 */
+ListCell *
+list_tail(List *l)
+{
+	return l ? l->tail : NULL;
+}
 
-	foreach(i, l1)
-	{
-		if (!ptrMember(lfirst(i), l2))
-			result = lappend(result, lfirst(i));
-	}
-	return result;
+int
+list_length(List *l)
+{
+	return l ? l->length : 0;
 }
 
+#endif /* ! __GNUC__ */
+
 /*
- * Reverse a list, non-destructively
+ * Temporary compatibility functions
+ *
+ * In order to avoid warnings for these function definitions, we need
+ * to include a prototype here as well as in pg_list.h. That's because
+ * we explicitly disable list API compatibility in list.c, so we
+ * don't see the prototypes for these functions.
  */
-#ifdef NOT_USED
+
+/*
+ * Given a list, return its length. This is merely defined for the
+ * sake of backward compatibility: we can't afford to define a macro
+ * called "length", so it must be a function. New code should use the
+ * list_length() macro in order to avoid the overhead of a function
+ * call.
+ */
+int length(List *list);
+
+int
+length(List *list)
+{
+	return list_length(list);
+}
+
+/*
+ * This code implements the old "Fast List" API, making use of the new
+ * List code to do so. There's no need for FastList anymore, so this
+ * code is a bit sloppy -- it will be removed soon.
+ */
+void FastListInit(FastList *fl);
+
+void
+FastListInit(FastList *fl)
+{
+	fl->list = NIL;
+}
+
+void FastListFromList(FastList *fl, List *l);
+
+void
+FastListFromList(FastList *fl, List *list)
+{
+	fl->list = list;
+}
+
+List *FastListValue(FastList *fl);
+
 List *
-lreverse(List *l)
+FastListValue(FastList *fl)
+{
+	return fl->list;
+}
+
+void makeFastList1(FastList *fl, void *elem);
+
+void
+makeFastList1(FastList *fl, void *elem)
 {
-	List	   *result = NIL;
-	List	   *i;
+	fl->list = list_make1(elem);
+}
 
-	foreach(i, l)
-		result = lcons(lfirst(i), result);
-	return result;
+void FastAppend(FastList *fl, void *datum);
+
+void
+FastAppend(FastList *fl, void *datum)
+{
+	fl->list = lappend(fl->list, datum);
 }
 
-#endif
+void FastAppendi(FastList *fl, int datum);
+
+void
+FastAppendi(FastList *fl, int datum)
+{
+	fl->list = lappend_int(fl->list, datum);
+}
+
+void FastAppendo(FastList *fl, Oid datum);
+
+void
+FastAppendo(FastList *fl, Oid datum)
+{
+	fl->list = lappend_oid(fl->list, datum);
+}
+
+void FastConc(FastList *fl, List *cells);
+
+void
+FastConc(FastList *fl, List *cells)
+{
+	fl->list = list_concat(fl->list, cells);
+}
+
+void FastConcFast(FastList *fl1, FastList *fl2);
+
+void
+FastConcFast(FastList *fl1, FastList *fl2)
+{
+	fl1->list = list_concat(fl1->list, fl2->list);
+}
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index e919a851940a8f241b9d45ceeac34080416e9807..f9e3f7fbcb6a43dd05c6160de45e5a28efd9081d 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.236 2004/05/10 22:44:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.237 2004/05/26 04:41:19 neilc Exp $
  *
  * NOTES
  *	  Every node type that can appear in stored rules' parsetrees *must*
@@ -19,6 +19,8 @@
  *
  *-------------------------------------------------------------------------
  */
+#define DISABLE_LIST_COMPAT
+
 #include "postgres.h"
 
 #include <ctype.h>
@@ -85,16 +87,6 @@
 	(appendStringInfo(str, " :" CppAsString(fldname) " "), \
 	 _outNode(str, node->fldname))
 
-/* Write an integer-list field */
-#define WRITE_INTLIST_FIELD(fldname) \
-	(appendStringInfo(str, " :" CppAsString(fldname) " "), \
-	 _outIntList(str, node->fldname))
-
-/* Write an OID-list field */
-#define WRITE_OIDLIST_FIELD(fldname) \
-	(appendStringInfo(str, " :" CppAsString(fldname) " "), \
-	 _outOidList(str, node->fldname))
-
 /* Write a bitmapset field */
 #define WRITE_BITMAPSET_FIELD(fldname) \
 	(appendStringInfo(str, " :" CppAsString(fldname) " "), \
@@ -145,35 +137,40 @@ _outToken(StringInfo str, char *s)
 	}
 }
 
-/*
- * _outIntList -
- *	   converts a List of integers
- */
 static void
-_outIntList(StringInfo str, List *list)
+_outList(StringInfo str, List *node)
 {
-	List	   *l;
+	ListCell *lc;
 
 	appendStringInfoChar(str, '(');
-	appendStringInfoChar(str, 'i');
-	foreach(l, list)
-		appendStringInfo(str, " %d", lfirsti(l));
-	appendStringInfoChar(str, ')');
-}
 
-/*
- * _outOidList -
- *	   converts a List of OIDs
- */
-static void
-_outOidList(StringInfo str, List *list)
-{
-	List	   *l;
+	if (IsA(node, IntList))
+		appendStringInfoChar(str, 'i');
+	else if (IsA(node, OidList))
+		appendStringInfoChar(str, 'o');
+
+	foreach (lc, node)
+	{
+		/*
+		 * For the sake of backward compatibility, we emit a slightly
+		 * different whitespace format for lists of nodes vs. other
+		 * types of lists. XXX: is this necessary?
+		 */
+		if (IsA(node, List))
+		{
+			_outNode(str, lfirst(lc));
+			if (lnext(lc))
+				appendStringInfoChar(str, ' ');
+		}
+		else if (IsA(node, IntList))
+			appendStringInfo(str, " %d", lfirst_int(lc));
+		else if (IsA(node, OidList))
+			appendStringInfo(str, " %u", lfirst_oid(lc));
+		else
+ 			elog(ERROR, "unrecognized list node type: %d",
+ 				 (int) node->type);
+	}
 
-	appendStringInfoChar(str, '(');
-	appendStringInfoChar(str, 'o');
-	foreach(l, list)
-		appendStringInfo(str, " %u", lfirsto(l));
 	appendStringInfoChar(str, ')');
 }
 
@@ -336,39 +333,12 @@ _outIndexScan(StringInfo str, IndexScan *node)
 
 	_outScanInfo(str, (Scan *) node);
 
-	WRITE_OIDLIST_FIELD(indxid);
+	WRITE_NODE_FIELD(indxid);
 	WRITE_NODE_FIELD(indxqual);
 	WRITE_NODE_FIELD(indxqualorig);
-	/* this can become WRITE_NODE_FIELD when intlists are normal objects: */
-	{
-		List    *tmp;
-
-		appendStringInfo(str, " :indxstrategy ");
-		foreach(tmp, node->indxstrategy)
-		{
-			_outIntList(str, lfirst(tmp));
-		}
-	}
-	/* this can become WRITE_NODE_FIELD when OID lists are normal objects: */
-	{
-		List    *tmp;
-
-		appendStringInfo(str, " :indxsubtype ");
-		foreach(tmp, node->indxsubtype)
-		{
-			_outOidList(str, lfirst(tmp));
-		}
-	}
-	/* this can become WRITE_NODE_FIELD when intlists are normal objects: */
-	{
-		List    *tmp;
-
-		appendStringInfo(str, " :indxlossy ");
-		foreach(tmp, node->indxlossy)
-		{
-			_outIntList(str, lfirst(tmp));
-		}
-	}
+	WRITE_NODE_FIELD(indxstrategy);
+	WRITE_NODE_FIELD(indxsubtype);
+	WRITE_NODE_FIELD(indxlossy);
 	WRITE_ENUM_FIELD(indxorderdir, ScanDirection);
 }
 
@@ -743,7 +713,7 @@ _outSubLink(StringInfo str, SubLink *node)
 	WRITE_BOOL_FIELD(useOr);
 	WRITE_NODE_FIELD(lefthand);
 	WRITE_NODE_FIELD(operName);
-	WRITE_OIDLIST_FIELD(operOids);
+	WRITE_NODE_FIELD(operOids);
 	WRITE_NODE_FIELD(subselect);
 }
 
@@ -755,14 +725,14 @@ _outSubPlan(StringInfo str, SubPlan *node)
 	WRITE_ENUM_FIELD(subLinkType, SubLinkType);
 	WRITE_BOOL_FIELD(useOr);
 	WRITE_NODE_FIELD(exprs);
-	WRITE_INTLIST_FIELD(paramIds);
+	WRITE_NODE_FIELD(paramIds);
 	WRITE_NODE_FIELD(plan);
 	WRITE_INT_FIELD(plan_id);
 	WRITE_NODE_FIELD(rtable);
 	WRITE_BOOL_FIELD(useHashTable);
 	WRITE_BOOL_FIELD(unknownEqFalse);
-	WRITE_INTLIST_FIELD(setParam);
-	WRITE_INTLIST_FIELD(parParam);
+	WRITE_NODE_FIELD(setParam);
+	WRITE_NODE_FIELD(parParam);
 	WRITE_NODE_FIELD(args);
 }
 
@@ -1302,7 +1272,7 @@ _outQuery(StringInfo str, Query *node)
 	WRITE_BOOL_FIELD(hasSubLinks);
 	WRITE_NODE_FIELD(rtable);
 	WRITE_NODE_FIELD(jointree);
-	WRITE_INTLIST_FIELD(rowMarks);
+	WRITE_NODE_FIELD(rowMarks);
 	WRITE_NODE_FIELD(targetList);
 	WRITE_NODE_FIELD(groupClause);
 	WRITE_NODE_FIELD(havingQual);
@@ -1311,7 +1281,7 @@ _outQuery(StringInfo str, Query *node)
 	WRITE_NODE_FIELD(limitOffset);
 	WRITE_NODE_FIELD(limitCount);
 	WRITE_NODE_FIELD(setOperations);
-	WRITE_INTLIST_FIELD(resultRelations);
+	WRITE_NODE_FIELD(resultRelations);
 
 	/* planner-internal fields are not written out */
 }
@@ -1343,7 +1313,7 @@ _outSetOperationStmt(StringInfo str, SetOperationStmt *node)
 	WRITE_BOOL_FIELD(all);
 	WRITE_NODE_FIELD(larg);
 	WRITE_NODE_FIELD(rarg);
-	WRITE_OIDLIST_FIELD(colTypes);
+	WRITE_NODE_FIELD(colTypes);
 }
 
 static void
@@ -1444,7 +1414,6 @@ _outValue(StringInfo str, Value *value)
 			appendStringInfo(str, "%ld", value->val.ival);
 			break;
 		case T_Float:
-
 			/*
 			 * We assume the value is a valid numeric literal and so does
 			 * not need quoting.
@@ -1572,24 +1541,9 @@ static void
 _outNode(StringInfo str, void *obj)
 {
 	if (obj == NULL)
-	{
 		appendStringInfo(str, "<>");
-		return;
-	}
-
-	if (IsA(obj, List))
-	{
-		List	   *l;
-
-		appendStringInfoChar(str, '(');
-		foreach(l, (List *) obj)
-		{
-			_outNode(str, lfirst(l));
-			if (lnext(l))
-				appendStringInfoChar(str, ' ');
-		}
-		appendStringInfoChar(str, ')');
-	}
+	else if (IsA(obj, List) || IsA(obj, IntList) || IsA(obj, OidList))
+		_outList(str, obj);
 	else if (IsA(obj, Integer) ||
 			 IsA(obj, Float) ||
 			 IsA(obj, String) ||
diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c
index 14f73b1860ea2d12a37b9dac644d915d7736c6d5..8da0726d7ccbd9793c878e690b44fa5a68a4c489 100644
--- a/src/backend/nodes/print.c
+++ b/src/backend/nodes/print.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/print.c,v 1.66 2004/05/08 21:21:18 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/print.c,v 1.67 2004/05/26 04:41:19 neilc Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -255,7 +255,7 @@ pretty_format_node_dump(const char *dump)
 void
 print_rt(List *rtable)
 {
-	List	   *l;
+	ListCell   *l;
 	int			i = 1;
 
 	printf("resno\trefname  \trelid\tinFromCl\n");
@@ -395,7 +395,7 @@ print_expr(Node *expr, List *rtable)
 	{
 		FuncExpr   *e = (FuncExpr *) expr;
 		char	   *funcname;
-		List	   *l;
+		ListCell   *l;
 
 		funcname = get_func_name(e->funcid);
 		printf("%s(", ((funcname != NULL) ? funcname : "(invalid function)"));
@@ -418,18 +418,18 @@ print_expr(Node *expr, List *rtable)
 void
 print_pathkeys(List *pathkeys, List *rtable)
 {
-	List	   *i,
-			   *k;
+	ListCell   *i;
 
 	printf("(");
 	foreach(i, pathkeys)
 	{
-		List	   *pathkey = lfirst(i);
+		List	   *pathkey = (List *) lfirst(i);
+		ListCell   *k;
 
 		printf("(");
 		foreach(k, pathkey)
 		{
-			PathKeyItem *item = lfirst(k);
+			PathKeyItem *item = (PathKeyItem *) lfirst(k);
 
 			print_expr(item->key, rtable);
 			if (lnext(k))
@@ -449,12 +449,12 @@ print_pathkeys(List *pathkeys, List *rtable)
 void
 print_tl(List *tlist, List *rtable)
 {
-	List	   *tl;
+	ListCell   *tl;
 
 	printf("(\n");
 	foreach(tl, tlist)
 	{
-		TargetEntry *tle = lfirst(tl);
+		TargetEntry *tle = (TargetEntry *) lfirst(tl);
 
 		printf("\t%d %s\t", tle->resdom->resno,
 			   tle->resdom->resname ? tle->resdom->resname : "<null>");
@@ -590,13 +590,13 @@ print_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label)
 
 	if (IsA(p, Append))
 	{
-		List	   *lst;
+		ListCell   *l;
 		int			whichplan = 0;
 		Append	   *appendplan = (Append *) p;
 
-		foreach(lst, appendplan->appendplans)
+		foreach(l, appendplan->appendplans)
 		{
-			Plan	   *subnode = (Plan *) lfirst(lst);
+			Plan	   *subnode = (Plan *) lfirst(l);
 
 			/*
 			 * I don't think we need to fiddle with the range table here,
diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c
index e90b413591c22f2bec2097dc55397b5d9879f1b5..6822909225be20835ad96a6421c622336a66a8ab 100644
--- a/src/backend/nodes/read.c
+++ b/src/backend/nodes/read.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/read.c,v 1.41 2004/05/08 21:21:18 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/read.c,v 1.42 2004/05/26 04:41:19 neilc Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -384,7 +384,6 @@ nodeRead(char *token, int tok_len)
 			}
 			break;
 		case T_Integer:
-
 			/*
 			 * we know that the token terminates on a char atol will stop
 			 * at
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 253b5a3eafa3c5ae8826b9c757f22124075e948c..792a6156eb895426f3ab0adec0a6a6cb859d3b17 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.169 2004/05/10 22:44:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.170 2004/05/26 04:41:19 neilc Exp $
  *
  * NOTES
  *	  Path and Plan nodes do not have any readfuncs support, because we
@@ -18,6 +18,8 @@
  *
  *-------------------------------------------------------------------------
  */
+#define DISABLE_LIST_COMPAT
+
 #include "postgres.h"
 
 #include <math.h>
@@ -33,21 +35,22 @@
  * routine.
  */
 
-/* Declare appropriate local variables */
-#define READ_LOCALS(nodeTypeName) \
-	nodeTypeName *local_node = makeNode(nodeTypeName); \
-	char	   *token; \
-	int			length
+/* Macros for declaring appropriate local variables */
 
 /* A few guys need only local_node */
 #define READ_LOCALS_NO_FIELDS(nodeTypeName) \
 	nodeTypeName *local_node = makeNode(nodeTypeName)
 
 /* And a few guys need only the pg_strtok support fields */
-#define READ_TEMP_LOCALS() \
-	char	   *token; \
+#define READ_TEMP_LOCALS()	\
+	char	   *token;		\
 	int			length
 
+/* ... but most need both */
+#define READ_LOCALS(nodeTypeName)			\
+	READ_LOCALS_NO_FIELDS(nodeTypeName);	\
+	READ_TEMP_LOCALS()
+
 /* Read an integer field (anything written as ":fldname %d") */
 #define READ_INT_FIELD(fldname) \
 	token = pg_strtok(&length);		/* skip :fldname */ \
@@ -101,16 +104,6 @@
 	token = pg_strtok(&length);		/* skip :fldname */ \
 	local_node->fldname = nodeRead(NULL, 0)
 
-/* Read an integer-list field (XXX combine me with READ_NODE_FIELD) */
-#define READ_INTLIST_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
-	local_node->fldname = nodeRead(NULL, 0)
-
-/* Read an OID-list field (XXX combine me with READ_NODE_FIELD) */
-#define READ_OIDLIST_FIELD(fldname) \
-	token = pg_strtok(&length);		/* skip :fldname */ \
-	local_node->fldname = nodeRead(NULL, 0)
-
 /* Routine exit */
 #define READ_DONE() \
 	return local_node
@@ -153,7 +146,7 @@ _readQuery(void)
 	READ_BOOL_FIELD(hasSubLinks);
 	READ_NODE_FIELD(rtable);
 	READ_NODE_FIELD(jointree);
-	READ_INTLIST_FIELD(rowMarks);
+	READ_NODE_FIELD(rowMarks);
 	READ_NODE_FIELD(targetList);
 	READ_NODE_FIELD(groupClause);
 	READ_NODE_FIELD(havingQual);
@@ -162,7 +155,7 @@ _readQuery(void)
 	READ_NODE_FIELD(limitOffset);
 	READ_NODE_FIELD(limitCount);
 	READ_NODE_FIELD(setOperations);
-	READ_INTLIST_FIELD(resultRelations);
+	READ_NODE_FIELD(resultRelations);
 
 	/* planner-internal fields are left zero */
 
@@ -237,7 +230,7 @@ _readSetOperationStmt(void)
 	READ_BOOL_FIELD(all);
 	READ_NODE_FIELD(larg);
 	READ_NODE_FIELD(rarg);
-	READ_OIDLIST_FIELD(colTypes);
+	READ_NODE_FIELD(colTypes);
 
 	READ_DONE();
 }
@@ -526,7 +519,7 @@ _readSubLink(void)
 	READ_BOOL_FIELD(useOr);
 	READ_NODE_FIELD(lefthand);
 	READ_NODE_FIELD(operName);
-	READ_OIDLIST_FIELD(operOids);
+	READ_NODE_FIELD(operOids);
 	READ_NODE_FIELD(subselect);
 
 	READ_DONE();
diff --git a/src/backend/optimizer/geqo/geqo_eval.c b/src/backend/optimizer/geqo/geqo_eval.c
index ccb095aad03bd528e34bd344a0b92a4697ba611a..1642f34b4087a3a5e7ab356a37798aaacb33f8eb 100644
--- a/src/backend/optimizer/geqo/geqo_eval.c
+++ b/src/backend/optimizer/geqo/geqo_eval.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_eval.c,v 1.67 2004/01/23 23:54:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_eval.c,v 1.68 2004/05/26 04:41:20 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -238,14 +238,14 @@ static bool
 desirable_join(Query *root,
 			   RelOptInfo *outer_rel, RelOptInfo *inner_rel)
 {
-	List	   *i;
+	ListCell   *l;
 
 	/*
 	 * Join if there is an applicable join clause.
 	 */
-	foreach(i, outer_rel->joininfo)
+	foreach(l, outer_rel->joininfo)
 	{
-		JoinInfo   *joininfo = (JoinInfo *) lfirst(i);
+		JoinInfo   *joininfo = (JoinInfo *) lfirst(l);
 
 		if (bms_is_subset(joininfo->unjoined_relids, inner_rel->relids))
 			return true;
@@ -256,9 +256,9 @@ desirable_join(Query *root,
 	 * needed to improve the odds that we will find a valid solution in
 	 * a case where an IN sub-select has a clauseless join.
 	 */
-	foreach(i, root->in_info_list)
+	foreach(l, root->in_info_list)
 	{
-		InClauseInfo *ininfo = (InClauseInfo *) lfirst(i);
+		InClauseInfo *ininfo = (InClauseInfo *) lfirst(l);
 
 		if (bms_is_subset(outer_rel->relids, ininfo->righthand) &&
 			bms_is_subset(inner_rel->relids, ininfo->righthand))
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 217f06a6b2bc207b57e8f817394d7ed2fcb710fc..a4bc92b1c3b80173481e536a91012f53f39d8ca3 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.114 2004/05/10 22:44:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.115 2004/05/26 04:41:21 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -102,11 +102,11 @@ make_one_rel(Query *root)
 static void
 set_base_rel_pathlists(Query *root)
 {
-	List	   *rellist;
+	ListCell	   *l;
 
-	foreach(rellist, root->base_rel_list)
+	foreach(l, root->base_rel_list)
 	{
-		RelOptInfo *rel = (RelOptInfo *) lfirst(rellist);
+		RelOptInfo *rel = (RelOptInfo *) lfirst(l);
 		Index		rti = rel->relid;
 		RangeTblEntry *rte;
 		List	   *inheritlist;
@@ -212,7 +212,7 @@ set_inherited_rel_pathlist(Query *root, RelOptInfo *rel,
 	int			parentRTindex = rti;
 	Oid			parentOID = rte->relid;
 	List	   *subpaths = NIL;
-	List	   *il;
+	ListCell   *il;
 
 	/*
 	 * XXX for now, can't handle inherited expansion of FOR UPDATE; can we
@@ -247,8 +247,8 @@ set_inherited_rel_pathlist(Query *root, RelOptInfo *rel,
 		Oid			childOID;
 		RelOptInfo *childrel;
 		List	   *reltlist;
-		List	   *parentvars;
-		List	   *childvars;
+		ListCell   *parentvars;
+		ListCell   *childvars;
 
 		childrte = rt_fetch(childRTindex, root->rtable);
 		childOID = childrte->relid;
@@ -300,7 +300,7 @@ set_inherited_rel_pathlist(Query *root, RelOptInfo *rel,
 		if (childrel->width > rel->width)
 			rel->width = childrel->width;
 
-		childvars = FastListValue(&childrel->reltargetlist);
+		childvars = list_head(FastListValue(&childrel->reltargetlist));
 		foreach(parentvars, FastListValue(&rel->reltargetlist))
 		{
 			Var		   *parentvar = (Var *) lfirst(parentvars);
@@ -366,11 +366,11 @@ set_subquery_pathlist(Query *root, RelOptInfo *rel,
 	{
 		/* OK to consider pushing down individual quals */
 		List	   *upperrestrictlist = NIL;
-		List	   *lst;
+		ListCell   *l;
 
-		foreach(lst, rel->baserestrictinfo)
+		foreach(l, rel->baserestrictinfo)
 		{
-			RestrictInfo *rinfo = (RestrictInfo *) lfirst(lst);
+			RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
 			Node	   *clause = (Node *) rinfo->clause;
 
 			if (qual_is_pushdown_safe(subquery, rti, clause, differentTypes))
@@ -434,7 +434,7 @@ make_fromexpr_rel(Query *root, FromExpr *from)
 {
 	int			levels_needed;
 	List	   *initial_rels = NIL;
-	List	   *jt;
+	ListCell   *jt;
 
 	/*
 	 * Count the number of child jointree nodes.  This is the depth of the
@@ -464,7 +464,7 @@ make_fromexpr_rel(Query *root, FromExpr *from)
 		/*
 		 * Single jointree node, so we're done.
 		 */
-		return (RelOptInfo *) lfirst(initial_rels);
+		return (RelOptInfo *) linitial(initial_rels);
 	}
 	else
 	{
@@ -516,7 +516,7 @@ make_one_rel_by_joins(Query *root, int levels_needed, List *initial_rels)
 
 	for (lev = 2; lev <= levels_needed; lev++)
 	{
-		List	   *x;
+		ListCell   *x;
 
 		/*
 		 * Determine all possible pairs of relations to be joined at this
@@ -548,7 +548,7 @@ make_one_rel_by_joins(Query *root, int levels_needed, List *initial_rels)
 		elog(ERROR, "failed to build any %d-way joins", levels_needed);
 	Assert(length(joinitems[levels_needed]) == 1);
 
-	rel = (RelOptInfo *) lfirst(joinitems[levels_needed]);
+	rel = (RelOptInfo *) linitial(joinitems[levels_needed]);
 
 	return rel;
 }
@@ -660,21 +660,22 @@ static void
 compare_tlist_datatypes(List *tlist, List *colTypes,
 						bool *differentTypes)
 {
-	List	   *i;
+	ListCell   *l;
+	ListCell   *colType = list_head(colTypes);
 
-	foreach(i, tlist)
+	foreach(l, tlist)
 	{
-		TargetEntry *tle = (TargetEntry *) lfirst(i);
+		TargetEntry *tle = (TargetEntry *) lfirst(l);
 
 		if (tle->resdom->resjunk)
 			continue;			/* ignore resjunk columns */
-		if (colTypes == NIL)
+		if (colType == NULL)
 			elog(ERROR, "wrong number of tlist entries");
-		if (tle->resdom->restype != lfirsto(colTypes))
+		if (tle->resdom->restype != lfirst_oid(colType))
 			differentTypes[tle->resdom->resno] = true;
-		colTypes = lnext(colTypes);
+		colType = lnext(colType);
 	}
-	if (colTypes != NIL)
+	if (colType != NULL)
 		elog(ERROR, "wrong number of tlist entries");
 }
 
@@ -712,7 +713,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
 {
 	bool		safe = true;
 	List	   *vars;
-	List	   *vl;
+	ListCell   *vl;
 	Bitmapset  *tested = NULL;
 
 	/* Refuse subselects (point 1) */
@@ -869,7 +870,7 @@ print_relids(Relids relids)
 static void
 print_restrictclauses(Query *root, List *clauses)
 {
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, clauses)
 	{
@@ -987,7 +988,7 @@ print_path(Query *root, Path *path, int indent)
 void
 debug_print_rel(Query *root, RelOptInfo *rel)
 {
-	List	   *l;
+	ListCell   *l;
 
 	printf("RELOPTINFO (");
 	print_relids(rel->relids);
diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c
index 96ce94c8fcbc0bc7c8f6b98666c32f94cd4bdd0d..c8b54bf223affd17e3111d8c53a751b2daaa06ce 100644
--- a/src/backend/optimizer/path/clausesel.c
+++ b/src/backend/optimizer/path/clausesel.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.65 2004/05/10 22:44:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.66 2004/05/26 04:41:21 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -98,16 +98,16 @@ clauselist_selectivity(Query *root,
 {
 	Selectivity s1 = 1.0;
 	RangeQueryClause *rqlist = NULL;
-	List	   *clist;
+	ListCell   *l;
 
 	/*
 	 * Initial scan over clauses.  Anything that doesn't look like a
 	 * potential rangequery clause gets multiplied into s1 and forgotten.
 	 * Anything that does gets inserted into an rqlist entry.
 	 */
-	foreach(clist, clauses)
+	foreach(l, clauses)
 	{
-		Node	   *clause = (Node *) lfirst(clist);
+		Node	   *clause = (Node *) lfirst(l);
 		RestrictInfo *rinfo;
 		Selectivity s2;
 
@@ -143,7 +143,7 @@ clauselist_selectivity(Query *root,
 					(is_pseudo_constant_clause_relids(lsecond(expr->args),
 													  rinfo->right_relids) ||
 					 (varonleft = false,
-					  is_pseudo_constant_clause_relids(lfirst(expr->args),
+					  is_pseudo_constant_clause_relids(linitial(expr->args),
 													   rinfo->left_relids)));
 			}
 			else
@@ -151,7 +151,7 @@ clauselist_selectivity(Query *root,
 				ok = (NumRelids(clause) == 1) &&
 					(is_pseudo_constant_clause(lsecond(expr->args)) ||
 					 (varonleft = false,
-					  is_pseudo_constant_clause(lfirst(expr->args))));
+					  is_pseudo_constant_clause(linitial(expr->args))));
 			}
 
 			if (ok)
@@ -521,7 +521,7 @@ clause_selectivity(Query *root,
 		 *
 		 * XXX is this too conservative?
 		 */
-		List	   *arg;
+		ListCell   *arg;
 
 		s1 = 0.0;
 		foreach(arg, ((BoolExpr *) clause)->args)
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 94ce4446fa27073a2e9b1cf98ee2699de78c9a3e..71b879b134a0231cc1ec3bf7e1cdf9a5714088e1 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -49,7 +49,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.126 2004/04/06 18:46:03 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.127 2004/05/26 04:41:21 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -920,7 +920,7 @@ cost_mergejoin(MergePath *path, Query *root)
 	 */
 	if (mergeclauses)
 	{
-		firstclause = (RestrictInfo *) lfirst(mergeclauses);
+		firstclause = (RestrictInfo *) linitial(mergeclauses);
 		if (firstclause->left_mergescansel < 0)	/* not computed yet? */
 			mergejoinscansel(root, (Node *) firstclause->clause,
 							 &firstclause->left_mergescansel,
@@ -1069,7 +1069,7 @@ cost_hashjoin(HashPath *path, Query *root)
 	int			numbatches;
 	Selectivity innerbucketsize;
 	Selectivity joininfactor;
-	List	   *hcl;
+	ListCell   *hcl;
 
 	if (!enable_hashjoin)
 		startup_cost += disable_cost;
@@ -1267,7 +1267,7 @@ cost_hashjoin(HashPath *path, Query *root)
 void
 cost_qual_eval(QualCost *cost, List *quals)
 {
-	List	   *l;
+	ListCell   *l;
 
 	cost->startup = 0;
 	cost->per_tuple = 0;
@@ -1444,7 +1444,7 @@ static Selectivity
 approx_selectivity(Query *root, List *quals, JoinType jointype)
 {
 	Selectivity total = 1.0;
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, quals)
 	{
@@ -1699,7 +1699,7 @@ static void
 set_rel_width(Query *root, RelOptInfo *rel)
 {
 	int32		tuple_width = 0;
-	List	   *tllist;
+	ListCell   *tllist;
 
 	foreach(tllist, FastListValue(&rel->reltargetlist))
 	{
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 565e9018daa81c0aafdb4099f60b5a7fc07b4a15..7c72b540647b2100a30cdbd22f5c093194ae5330 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.158 2004/03/27 00:24:28 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.159 2004/05/26 04:41:21 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -121,7 +121,7 @@ void
 create_index_paths(Query *root, RelOptInfo *rel)
 {
 	Relids		all_join_outerrelids = NULL;
-	List	   *ilist;
+	ListCell   *ilist;
 
 	foreach(ilist, rel->indexlist)
 	{
@@ -250,12 +250,12 @@ group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index)
 	{
 		Oid			curClass = classes[0];
 		FastList	clausegroup;
-		List	   *i;
+		ListCell   *l;
 
 		FastListInit(&clausegroup);
-		foreach(i, restrictinfo_list)
+		foreach(l, restrictinfo_list)
 		{
-			RestrictInfo *rinfo = (RestrictInfo *) lfirst(i);
+			RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
 
 			if (match_clause_to_indexcol(rel,
 										 index,
@@ -312,7 +312,7 @@ group_clauses_by_indexkey_for_join(Query *root,
 		Oid			curClass = classes[0];
 		FastList	clausegroup;
 		int			numsources;
-		List	   *i;
+		ListCell   *l;
 
 		FastListInit(&clausegroup);
 
@@ -324,9 +324,9 @@ group_clauses_by_indexkey_for_join(Query *root,
 		 * of a non-join clause if it appears after a join clause it is
 		 * redundant with.
 		 */
-		foreach(i, rel->baserestrictinfo)
+		foreach(l, rel->baserestrictinfo)
 		{
-			RestrictInfo *rinfo = (RestrictInfo *) lfirst(i);
+			RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
 
 			/* Can't use pushed-down clauses in outer join */
 			if (isouterjoin && rinfo->is_pushed_down)
@@ -344,11 +344,11 @@ group_clauses_by_indexkey_for_join(Query *root,
 		numsources = (FastListValue(&clausegroup) != NIL) ? 1 : 0;
 
 		/* Look for joinclauses that are usable with given outer_relids */
-		foreach(i, rel->joininfo)
+		foreach(l, rel->joininfo)
 		{
-			JoinInfo   *joininfo = (JoinInfo *) lfirst(i);
+			JoinInfo   *joininfo = (JoinInfo *) lfirst(l);
 			bool		jfoundhere = false;
-			List	   *j;
+			ListCell   *j;
 
 			if (!bms_is_subset(joininfo->unjoined_relids, outer_relids))
 				continue;
@@ -448,7 +448,7 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel,
 	{
 		Oid			curClass = classes[0];
 		FastList	clausegroup;
-		List	   *item;
+		ListCell   *item;
 
 		FastListInit(&clausegroup);
 
@@ -511,7 +511,6 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel,
 
 		indexcol++;
 		classes++;
-
 	} while (!DoneMatchingIndexKeys(classes));
 
 	/* if OR clause was not used then forget it, per comments above */
@@ -738,7 +737,7 @@ void
 check_partial_indexes(Query *root, RelOptInfo *rel)
 {
 	List	   *restrictinfo_list = rel->baserestrictinfo;
-	List	   *ilist;
+	ListCell   *ilist;
 
 	foreach(ilist, rel->indexlist)
 	{
@@ -772,7 +771,7 @@ check_partial_indexes(Query *root, RelOptInfo *rel)
 static bool
 pred_test(List *predicate_list, List *restrictinfo_list)
 {
-	List	   *pred;
+	ListCell   *pred;
 
 	/*
 	 * Note: if Postgres tried to optimize queries by forming equivalence
@@ -815,7 +814,7 @@ pred_test(List *predicate_list, List *restrictinfo_list)
 static bool
 pred_test_restrict_list(Expr *predicate, List *restrictinfo_list)
 {
-	List	   *item;
+	ListCell   *item;
 
 	foreach(item, restrictinfo_list)
 	{
@@ -839,8 +838,8 @@ pred_test_restrict_list(Expr *predicate, List *restrictinfo_list)
 static bool
 pred_test_recurse_clause(Expr *predicate, Node *clause)
 {
-	List	   *items,
-			   *item;
+	List	   *items;
+	ListCell   *item;
 
 	Assert(clause != NULL);
 	if (or_clause(clause))
@@ -883,8 +882,8 @@ pred_test_recurse_clause(Expr *predicate, Node *clause)
 static bool
 pred_test_recurse_pred(Expr *predicate, Node *clause)
 {
-	List	   *items,
-			   *item;
+	List	   *items;
+	ListCell   *item;
 
 	Assert(predicate != NULL);
 	if (or_clause((Node *) predicate))
@@ -1360,13 +1359,13 @@ static Relids
 indexable_outerrelids(RelOptInfo *rel, IndexOptInfo *index)
 {
 	Relids		outer_relids = NULL;
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, rel->joininfo)
+	foreach(l, rel->joininfo)
 	{
-		JoinInfo   *joininfo = (JoinInfo *) lfirst(i);
+		JoinInfo   *joininfo = (JoinInfo *) lfirst(l);
 		bool		match_found = false;
-		List	   *j;
+		ListCell   *j;
 
 		/*
 		 * Examine each joinclause in the JoinInfo node's list to see if
@@ -1433,8 +1432,8 @@ best_inner_indexscan(Query *root, RelOptInfo *rel,
 {
 	Path	   *cheapest = NULL;
 	bool		isouterjoin;
-	List	   *ilist;
-	List	   *jlist;
+	ListCell   *ilist;
+	ListCell   *jlist;
 	InnerIndexscanInfo *info;
 	MemoryContext oldcontext;
 
@@ -1538,7 +1537,7 @@ best_inner_indexscan(Query *root, RelOptInfo *rel,
 			}
 		}
 
-		if (jlist == NIL)		/* failed to find a match? */
+		if (jlist == NULL)		/* failed to find a match? */
 		{
 			List	   *clausegroups;
 
@@ -1676,7 +1675,7 @@ List *
 flatten_clausegroups_list(List *clausegroups)
 {
 	List	   *allclauses = NIL;
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, clausegroups)
 	{
@@ -1697,7 +1696,7 @@ Expr *
 make_expr_from_indexclauses(List *indexclauses)
 {
 	List	   *orclauses = NIL;
-	List	   *orlist;
+	ListCell   *orlist;
 
 	/* There's no such thing as an indexpath with zero scans */
 	Assert(indexclauses != NIL);
@@ -1715,7 +1714,7 @@ make_expr_from_indexclauses(List *indexclauses)
 	if (length(orclauses) > 1)
 		return make_orclause(orclauses);
 	else
-		return (Expr *) lfirst(orclauses);
+		return (Expr *) linitial(orclauses);
 }
 
 
@@ -1768,23 +1767,23 @@ match_index_to_operand(Node *operand,
 		 * could be avoided, at the cost of complicating all the callers
 		 * of this routine; doesn't seem worth it.)
 		 */
-		List	   *indexprs;
+		ListCell   *indexpr_item;
 		int			i;
 		Node	   *indexkey;
 
-		indexprs = index->indexprs;
+		indexpr_item = list_head(index->indexprs);
 		for (i = 0; i < indexcol; i++)
 		{
 			if (index->indexkeys[i] == 0)
 			{
-				if (indexprs == NIL)
+				if (indexpr_item == NULL)
 					elog(ERROR, "wrong number of index expressions");
-				indexprs = lnext(indexprs);
+				indexpr_item = lnext(indexpr_item);
 			}
 		}
-		if (indexprs == NIL)
+		if (indexpr_item == NULL)
 			elog(ERROR, "wrong number of index expressions");
-		indexkey = (Node *) lfirst(indexprs);
+		indexkey = (Node *) lfirst(indexpr_item);
 
 		/*
 		 * Does it match the operand?  Again, strip any relabeling.
@@ -2013,32 +2012,32 @@ List *
 expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
 {
 	FastList	resultquals;
+	ListCell   *clausegroup_item;
 	Oid		   *classes = index->classlist;
 
 	if (clausegroups == NIL)
 		return NIL;
 
 	FastListInit(&resultquals);
+	clausegroup_item = list_head(clausegroups);
 	do
 	{
 		Oid			curClass = classes[0];
-		List	   *i;
+		ListCell   *l;
 
-		foreach(i, (List *) lfirst(clausegroups))
+		foreach(l, (List *) lfirst(clausegroup_item))
 		{
-			RestrictInfo *rinfo = (RestrictInfo *) lfirst(i);
+			RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
 
 			FastConc(&resultquals,
 					 expand_indexqual_condition(rinfo, curClass));
 		}
 
-		clausegroups = lnext(clausegroups);
-
+		clausegroup_item = lnext(clausegroup_item);
 		classes++;
+	} while (clausegroup_item != NULL && !DoneMatchingIndexKeys(classes));
 
-	} while (clausegroups != NIL && !DoneMatchingIndexKeys(classes));
-
-	Assert(clausegroups == NIL);	/* else more groups than indexkeys... */
+	Assert(clausegroup_item == NULL);	/* else more groups than indexkeys... */
 
 	return FastListValue(&resultquals);
 }
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index ac6838d26e01fa604bed2305999b982f66bb2f11..e854fe03b77dddaf00b0f7a1e5860627ba24b8e3 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.86 2004/04/06 18:46:03 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.87 2004/05/26 04:41:22 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -145,7 +145,7 @@ sort_inner_and_outer(Query *root,
 	Path	   *outer_path;
 	Path	   *inner_path;
 	List	   *all_pathkeys;
-	List	   *i;
+	ListCell   *l;
 
 	/*
 	 * If we are doing a right or full join, we must use *all* the
@@ -224,9 +224,9 @@ sort_inner_and_outer(Query *root,
 												  mergeclause_list,
 												  outerrel);
 
-	foreach(i, all_pathkeys)
+	foreach(l, all_pathkeys)
 	{
-		List	   *front_pathkey = lfirst(i);
+		List	   *front_pathkey = (List *) lfirst(l);
 		List	   *cur_pathkeys;
 		List	   *cur_mergeclauses;
 		List	   *outerkeys;
@@ -234,7 +234,7 @@ sort_inner_and_outer(Query *root,
 		List	   *merge_pathkeys;
 
 		/* Make a pathkey list with this guy first. */
-		if (i != all_pathkeys)
+		if (l != list_head(all_pathkeys))
 			cur_pathkeys = lcons(front_pathkey,
 								 lremove(front_pathkey,
 										 listCopy(all_pathkeys)));
@@ -338,7 +338,7 @@ match_unsorted_outer(Query *root,
 	Path	   *inner_cheapest_total = innerrel->cheapest_total_path;
 	Path	   *matpath = NULL;
 	Path	   *bestinnerjoin = NULL;
-	List	   *i;
+	ListCell   *l;
 
 	/*
 	 * Nestloop only supports inner, left, and IN joins.  Also, if we are
@@ -402,9 +402,9 @@ match_unsorted_outer(Query *root,
 											 outerrel->relids, jointype);
 	}
 
-	foreach(i, outerrel->pathlist)
+	foreach(l, outerrel->pathlist)
 	{
-		Path	   *outerpath = (Path *) lfirst(i);
+		Path	   *outerpath = (Path *) lfirst(l);
 		List	   *merge_pathkeys;
 		List	   *mergeclauses;
 		List	   *innersortkeys;
@@ -676,7 +676,7 @@ hash_inner_and_outer(Query *root,
 {
 	bool		isouterjoin;
 	List	   *hashclauses;
-	List	   *i;
+	ListCell   *l;
 
 	/*
 	 * Hashjoin only supports inner, left, and IN joins.
@@ -704,9 +704,9 @@ hash_inner_and_outer(Query *root,
 	 * are usable with this pair of sub-relations.
 	 */
 	hashclauses = NIL;
-	foreach(i, restrictlist)
+	foreach(l, restrictlist)
 	{
-		RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i);
+		RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
 
 		if (!restrictinfo->can_join ||
 			restrictinfo->hashjoinoperator == InvalidOid)
@@ -803,11 +803,11 @@ select_mergejoin_clauses(RelOptInfo *joinrel,
 {
 	List	   *result_list = NIL;
 	bool		isouterjoin = IS_OUTER_JOIN(jointype);
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, restrictlist)
+	foreach(l, restrictlist)
 	{
-		RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i);
+		RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
 
 		/*
 		 * If processing an outer join, only use its own join clauses in
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 07caab48ac682e3498b9960661d01c6041127b97..6debd825c11e392e32bfa59626910451954ac641 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.67 2004/03/08 17:20:17 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/joinrels.c,v 1.68 2004/05/26 04:41:22 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,10 +20,10 @@
 
 static List *make_rels_by_clause_joins(Query *root,
 						  RelOptInfo *old_rel,
-						  List *other_rels);
+						  ListCell *other_rels);
 static List *make_rels_by_clauseless_joins(Query *root,
 							  RelOptInfo *old_rel,
-							  List *other_rels);
+							  ListCell *other_rels);
 static bool is_inside_IN(Query *root, RelOptInfo *rel);
 
 
@@ -43,8 +43,8 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
 {
 	List	   *result_rels = NIL;
 	List	   *new_rels;
-	List	   *nr;
-	List	   *r;
+	ListCell   *nr;
+	ListCell   *r;
 	int			k;
 
 	/*
@@ -64,13 +64,13 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
 	foreach(r, joinrels[level - 1])
 	{
 		RelOptInfo *old_rel = (RelOptInfo *) lfirst(r);
-		List	   *other_rels;
+		ListCell   *other_rels;
 
 		if (level == 2)
 			other_rels = lnext(r);		/* only consider remaining initial
 										 * rels */
 		else
-			other_rels = joinrels[1];	/* consider all initial rels */
+			other_rels = list_head(joinrels[1]);	/* consider all initial rels */
 
 		if (old_rel->joininfo != NIL)
 		{
@@ -149,8 +149,8 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
 		foreach(r, joinrels[k])
 		{
 			RelOptInfo *old_rel = (RelOptInfo *) lfirst(r);
-			List	   *other_rels;
-			List	   *r2;
+			ListCell   *other_rels;
+			ListCell   *r2;
 
 			if (old_rel->joininfo == NIL)
 				continue;		/* we ignore clauseless joins here */
@@ -158,15 +158,15 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
 			if (k == other_level)
 				other_rels = lnext(r);	/* only consider remaining rels */
 			else
-				other_rels = joinrels[other_level];
+				other_rels = list_head(joinrels[other_level]);
 
-			foreach(r2, other_rels)
+			for_each_cell(r2, other_rels)
 			{
 				RelOptInfo *new_rel = (RelOptInfo *) lfirst(r2);
 
 				if (!bms_overlap(old_rel->relids, new_rel->relids))
 				{
-					List	   *i;
+					ListCell   *i;
 
 					/*
 					 * OK, we can build a rel of the right level from this
@@ -217,14 +217,14 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
 		foreach(r, joinrels[level - 1])
 		{
 			RelOptInfo *old_rel = (RelOptInfo *) lfirst(r);
-			List	   *other_rels;
+			ListCell   *other_rels;
 
 			if (level == 2)
 				other_rels = lnext(r);	/* only consider remaining initial
 										 * rels */
 			else
-				other_rels = joinrels[1];		/* consider all initial
-												 * rels */
+				other_rels = list_head(joinrels[1]); /* consider all initial
+													  * rels */
 
 			new_rels = make_rels_by_clauseless_joins(root,
 													 old_rel,
@@ -271,7 +271,8 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
  *	  The join rel nodes are returned in a list.
  *
  * 'old_rel' is the relation entry for the relation to be joined
- * 'other_rels': other rels to be considered for joining
+ * 'other_rels': the first cell in a linked list containing the other
+ * rels to be considered for joining
  *
  * Currently, this is only used with initial rels in other_rels, but it
  * will work for joining to joinrels too, if the caller ensures there is no
@@ -282,10 +283,10 @@ make_rels_by_joins(Query *root, int level, List **joinrels)
 static List *
 make_rels_by_clause_joins(Query *root,
 						  RelOptInfo *old_rel,
-						  List *other_rels)
+						  ListCell *other_rels)
 {
 	List	   *result = NIL;
-	List	   *i,
+	ListCell   *i,
 			   *j;
 
 	foreach(i, old_rel->joininfo)
@@ -293,7 +294,7 @@ make_rels_by_clause_joins(Query *root,
 		JoinInfo   *joininfo = (JoinInfo *) lfirst(i);
 		Relids		unjoined_relids = joininfo->unjoined_relids;
 
-		foreach(j, other_rels)
+		for_each_cell(j, other_rels)
 		{
 			RelOptInfo *other_rel = (RelOptInfo *) lfirst(j);
 
@@ -324,7 +325,8 @@ make_rels_by_clause_joins(Query *root,
  *	  The join rel nodes are returned in a list.
  *
  * 'old_rel' is the relation entry for the relation to be joined
- * 'other_rels': other rels to be considered for joining
+ * 'other_rels': the first cell of a linked list containing the
+ * other rels to be considered for joining
  *
  * Currently, this is only used with initial rels in other_rels, but it would
  * work for joining to joinrels too.
@@ -332,12 +334,12 @@ make_rels_by_clause_joins(Query *root,
 static List *
 make_rels_by_clauseless_joins(Query *root,
 							  RelOptInfo *old_rel,
-							  List *other_rels)
+							  ListCell *other_rels)
 {
 	List	   *result = NIL;
-	List	   *i;
+	ListCell   *i;
 
-	foreach(i, other_rels)
+	for_each_cell(i, other_rels)
 	{
 		RelOptInfo *other_rel = (RelOptInfo *) lfirst(i);
 
@@ -370,11 +372,11 @@ make_rels_by_clauseless_joins(Query *root,
 static bool
 is_inside_IN(Query *root, RelOptInfo *rel)
 {
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, root->in_info_list)
+	foreach(l, root->in_info_list)
 	{
-		InClauseInfo *ininfo = (InClauseInfo *) lfirst(i);
+		InClauseInfo *ininfo = (InClauseInfo *) lfirst(l);
 
 		if (bms_is_subset(rel->relids, ininfo->righthand))
 			return true;
@@ -476,7 +478,7 @@ make_join_rel(Query *root, RelOptInfo *rel1, RelOptInfo *rel2,
 	 */
 	if (jointype == JOIN_INNER)
 	{
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, root->in_info_list)
 		{
diff --git a/src/backend/optimizer/path/orindxpath.c b/src/backend/optimizer/path/orindxpath.c
index 9722b69965dfb8e85119a3f254df10920b5fe84c..cc160e7a46e3ceb9344dc672a6d1dfcc449d6d35 100644
--- a/src/backend/optimizer/path/orindxpath.c
+++ b/src/backend/optimizer/path/orindxpath.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.57 2004/01/05 23:39:54 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.58 2004/05/26 04:41:22 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -100,7 +100,7 @@ create_or_index_quals(Query *root, RelOptInfo *rel)
 	RestrictInfo *or_rinfo;
 	Selectivity or_selec,
 				orig_selec;
-	List	   *i;
+	ListCell   *i;
 
 	/*
 	 * We use the best_or_subclause_indexes() machinery to locate the
@@ -111,7 +111,7 @@ create_or_index_quals(Query *root, RelOptInfo *rel)
 	foreach(i, rel->joininfo)
 	{
 		JoinInfo   *joininfo = (JoinInfo *) lfirst(i);
-		List	   *j;
+		ListCell   *j;
 
 		foreach(j, joininfo->jinfo_restrictinfo)
 		{
@@ -150,7 +150,7 @@ create_or_index_quals(Query *root, RelOptInfo *rel)
 	newrinfos = make_restrictinfo_from_indexclauses(bestpath->indexclauses,
 													true, true);
 	Assert(length(newrinfos) == 1);
-	or_rinfo = (RestrictInfo *) lfirst(newrinfos);
+	or_rinfo = (RestrictInfo *) linitial(newrinfos);
 	rel->baserestrictinfo = nconc(rel->baserestrictinfo, newrinfos);
 
 	/*
@@ -190,15 +190,15 @@ create_or_index_quals(Query *root, RelOptInfo *rel)
 void
 create_or_index_paths(Query *root, RelOptInfo *rel)
 {
-	List	   *i;
+	ListCell   *l;
 
 	/*
 	 * Check each restriction clause to see if it is an OR clause, and if so,
 	 * try to make a path using it.
 	 */
-	foreach(i, rel->baserestrictinfo)
+	foreach(l, rel->baserestrictinfo)
 	{
-		RestrictInfo *rinfo = (RestrictInfo *) lfirst(i);
+		RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
 
 		if (restriction_is_or_clause(rinfo))
 		{
@@ -248,7 +248,7 @@ best_or_subclause_indexes(Query *root,
 	FastList	quals;
 	Cost		path_startup_cost;
 	Cost		path_total_cost;
-	List	   *slist;
+	ListCell   *slist;
 	IndexPath  *pathnode;
 
 	FastListInit(&infos);
@@ -283,7 +283,7 @@ best_or_subclause_indexes(Query *root,
 		 *
 		 * Total cost is sum of the per-scan costs.
 		 */
-		if (slist == subclauses)	/* first scan? */
+		if (slist == list_head(subclauses))	/* first scan? */
 			path_startup_cost = best_startup_cost;
 		path_total_cost += best_total_cost;
 	}
@@ -351,7 +351,7 @@ best_or_subclause_index(Query *root,
 						Cost *retTotalCost)		/* return value */
 {
 	bool		found = false;
-	List	   *ilist;
+	ListCell   *ilist;
 
 	foreach(ilist, rel->indexlist)
 	{
diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c
index 65eb5cb8a6502e24f60207a78e304407bef30a53..af232bd0c985d353fa8247948cc88a4d31f51341 100644
--- a/src/backend/optimizer/path/pathkeys.c
+++ b/src/backend/optimizer/path/pathkeys.c
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.56 2004/04/07 17:42:28 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.57 2004/05/26 04:41:22 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -95,8 +95,8 @@ add_equijoined_keys(Query *root, RestrictInfo *restrictinfo)
 	PathKeyItem *item2 = makePathKeyItem(get_rightop(clause),
 										 restrictinfo->right_sortop,
 										 false);
-	List	   *newset,
-			   *cursetlink;
+	List	   *newset;
+	ListCell   *cursetlink;
 
 	/* We might see a clause X=X; don't make a single-element list from it */
 	if (equal(item1, item2))
@@ -122,10 +122,10 @@ add_equijoined_keys(Query *root, RestrictInfo *restrictinfo)
 	newset = NIL;
 
 	/* cannot use foreach here because of possible lremove */
-	cursetlink = root->equi_key_list;
+	cursetlink = list_head(root->equi_key_list);
 	while (cursetlink)
 	{
-		List	   *curset = lfirst(cursetlink);
+		List	   *curset = (List *) lfirst(cursetlink);
 		bool		item1here = member(item1, curset);
 		bool		item2here = member(item2, curset);
 
@@ -199,15 +199,15 @@ add_equijoined_keys(Query *root, RestrictInfo *restrictinfo)
 void
 generate_implied_equalities(Query *root)
 {
-	List	   *cursetlink;
+	ListCell   *cursetlink;
 
 	foreach(cursetlink, root->equi_key_list)
 	{
-		List	   *curset = lfirst(cursetlink);
+		List	   *curset = (List *) lfirst(cursetlink);
 		int			nitems = length(curset);
 		Relids	   *relids;
 		bool		have_consts;
-		List	   *ptr1;
+		ListCell   *ptr1;
 		int			i1;
 
 		/*
@@ -245,10 +245,10 @@ generate_implied_equalities(Query *root)
 		{
 			PathKeyItem *item1 = (PathKeyItem *) lfirst(ptr1);
 			bool		i1_is_variable = !bms_is_empty(relids[i1]);
-			List	   *ptr2;
+			ListCell   *ptr2;
 			int			i2 = i1 + 1;
 
-			foreach(ptr2, lnext(ptr1))
+			for_each_cell(ptr2, lnext(ptr1))
 			{
 				PathKeyItem *item2 = (PathKeyItem *) lfirst(ptr2);
 				bool		i2_is_variable = !bms_is_empty(relids[i2]);
@@ -294,14 +294,14 @@ generate_implied_equalities(Query *root)
 bool
 exprs_known_equal(Query *root, Node *item1, Node *item2)
 {
-	List	   *cursetlink;
+	ListCell   *cursetlink;
 
 	foreach(cursetlink, root->equi_key_list)
 	{
-		List	   *curset = lfirst(cursetlink);
+		List	   *curset = (List *) lfirst(cursetlink);
 		bool		item1member = false;
 		bool		item2member = false;
-		List	   *ptr;
+		ListCell   *ptr;
 
 		foreach(ptr, curset)
 		{
@@ -334,12 +334,12 @@ exprs_known_equal(Query *root, Node *item1, Node *item2)
 static List *
 make_canonical_pathkey(Query *root, PathKeyItem *item)
 {
-	List	   *cursetlink;
 	List	   *newset;
+	ListCell   *cursetlink;
 
 	foreach(cursetlink, root->equi_key_list)
 	{
-		List	   *curset = lfirst(cursetlink);
+		List	   *curset = (List *) lfirst(cursetlink);
 
 		if (member(item, curset))
 			return curset;
@@ -360,11 +360,11 @@ List *
 canonicalize_pathkeys(Query *root, List *pathkeys)
 {
 	List	   *new_pathkeys = NIL;
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, pathkeys)
+	foreach(l, pathkeys)
 	{
-		List	   *pathkey = (List *) lfirst(i);
+		List	   *pathkey = (List *) lfirst(l);
 		PathKeyItem *item;
 		List	   *cpathkey;
 
@@ -374,7 +374,7 @@ canonicalize_pathkeys(Query *root, List *pathkeys)
 		 * set by definition.
 		 */
 		Assert(pathkey != NIL);
-		item = (PathKeyItem *) lfirst(pathkey);
+		item = (PathKeyItem *) linitial(pathkey);
 		cpathkey = make_canonical_pathkey(root, item);
 
 		/*
@@ -402,11 +402,11 @@ canonicalize_pathkeys(Query *root, List *pathkeys)
 static int
 count_canonical_peers(Query *root, PathKeyItem *item)
 {
-	List	   *cursetlink;
+	ListCell   *cursetlink;
 
 	foreach(cursetlink, root->equi_key_list)
 	{
-		List	   *curset = lfirst(cursetlink);
+		List	   *curset = (List *) lfirst(cursetlink);
 
 		if (member(item, curset))
 			return length(curset) - 1;
@@ -430,15 +430,13 @@ count_canonical_peers(Query *root, PathKeyItem *item)
 PathKeysComparison
 compare_pathkeys(List *keys1, List *keys2)
 {
-	List	   *key1,
+	ListCell   *key1,
 			   *key2;
 
-	for (key1 = keys1, key2 = keys2;
-		 key1 != NIL && key2 != NIL;
-		 key1 = lnext(key1), key2 = lnext(key2))
+	forboth(key1, keys1, key2, keys2)
 	{
-		List	   *subkey1 = lfirst(key1);
-		List	   *subkey2 = lfirst(key2);
+		List	   *subkey1 = (List *) lfirst(key1);
+		List	   *subkey2 = (List *) lfirst(key2);
 
 		/*
 		 * XXX would like to check that we've been given canonicalized
@@ -465,9 +463,9 @@ compare_pathkeys(List *keys1, List *keys2)
 	 * the other list are not NIL --- no pathkey list should ever have a
 	 * NIL sublist.)
 	 */
-	if (key1 == NIL && key2 == NIL)
+	if (key1 == NULL && key2 == NULL)
 		return PATHKEYS_EQUAL;
-	if (key1 != NIL)
+	if (key1 != NULL)
 		return PATHKEYS_BETTER1;	/* key1 is longer */
 	return PATHKEYS_BETTER2;	/* key2 is longer */
 }
@@ -493,15 +491,13 @@ compare_pathkeys(List *keys1, List *keys2)
 PathKeysComparison
 compare_noncanonical_pathkeys(List *keys1, List *keys2)
 {
-	List	   *key1,
+	ListCell   *key1,
 			   *key2;
 
-	for (key1 = keys1, key2 = keys2;
-		 key1 != NIL && key2 != NIL;
-		 key1 = lnext(key1), key2 = lnext(key2))
+	forboth(key1, keys1, key2, keys2)
 	{
-		List	   *subkey1 = lfirst(key1);
-		List	   *subkey2 = lfirst(key2);
+		List	   *subkey1 = (List *) lfirst(key1);
+		List	   *subkey2 = (List *) lfirst(key2);
 
 		Assert(length(subkey1) == 1);
 		Assert(length(subkey2) == 1);
@@ -515,9 +511,9 @@ compare_noncanonical_pathkeys(List *keys1, List *keys2)
 	 * the other list are not NIL --- no pathkey list should ever have a
 	 * NIL sublist.)
 	 */
-	if (key1 == NIL && key2 == NIL)
+	if (key1 == NULL && key2 == NULL)
 		return PATHKEYS_EQUAL;
-	if (key1 != NIL)
+	if (key1 != NULL)
 		return PATHKEYS_BETTER1;	/* key1 is longer */
 	return PATHKEYS_BETTER2;	/* key2 is longer */
 }
@@ -573,11 +569,11 @@ get_cheapest_path_for_pathkeys(List *paths, List *pathkeys,
 							   CostSelector cost_criterion)
 {
 	Path	   *matched_path = NULL;
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, paths)
+	foreach(l, paths)
 	{
-		Path	   *path = (Path *) lfirst(i);
+		Path	   *path = (Path *) lfirst(l);
 
 		/*
 		 * Since cost comparison is a lot cheaper than pathkey comparison,
@@ -612,11 +608,11 @@ get_cheapest_fractional_path_for_pathkeys(List *paths,
 										  double fraction)
 {
 	Path	   *matched_path = NULL;
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, paths)
+	foreach(l, paths)
 	{
-		Path	   *path = (Path *) lfirst(i);
+		Path	   *path = (Path *) lfirst(l);
 
 		/*
 		 * Since cost comparison is a lot cheaper than pathkey comparison,
@@ -658,7 +654,7 @@ build_index_pathkeys(Query *root,
 	List	   *retval = NIL;
 	int		   *indexkeys = index->indexkeys;
 	Oid		   *ordering = index->ordering;
-	List	   *indexprs = index->indexprs;
+	ListCell   *indexprs_item = list_head(index->indexprs);
 
 	while (*ordering != InvalidOid)
 	{
@@ -683,10 +679,10 @@ build_index_pathkeys(Query *root,
 		else
 		{
 			/* expression --- assume we need not copy it */
-			if (indexprs == NIL)
+			if (indexprs_item == NULL)
 				elog(ERROR, "wrong number of index expressions");
-			indexkey = (Node *) lfirst(indexprs);
-			indexprs = lnext(indexprs);
+			indexkey = (Node *) lfirst(indexprs_item);
+			indexprs_item = lnext(indexprs_item);
 		}
 
 		/* OK, make a sublist for this sort key */
@@ -719,7 +715,7 @@ build_index_pathkeys(Query *root,
 static Var *
 find_indexkey_var(Query *root, RelOptInfo *rel, AttrNumber varattno)
 {
-	List	   *temp;
+	ListCell   *temp;
 	Index		relid;
 	Oid			reloid,
 				vartypeid;
@@ -758,12 +754,12 @@ build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery)
 	int			retvallen = 0;
 	int			outer_query_keys = length(root->query_pathkeys);
 	List	   *sub_tlist = rel->subplan->targetlist;
-	List	   *l;
+	ListCell   *i;
 
-	foreach(l, subquery->query_pathkeys)
+	foreach(i, subquery->query_pathkeys)
 	{
-		List	   *sub_pathkey = (List *) lfirst(l);
-		List	   *j;
+		List	   *sub_pathkey = (List *) lfirst(i);
+		ListCell   *j;
 		PathKeyItem *best_item = NULL;
 		int			best_score = 0;
 		List	   *cpathkey;
@@ -788,7 +784,7 @@ build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery)
 		{
 			PathKeyItem *sub_item = (PathKeyItem *) lfirst(j);
 			Node	   *sub_key = sub_item->key;
-			List	   *k;
+			ListCell   *k;
 
 			foreach(k, sub_tlist)
 			{
@@ -908,11 +904,11 @@ make_pathkeys_for_sortclauses(List *sortclauses,
 							  List *tlist)
 {
 	List	   *pathkeys = NIL;
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, sortclauses)
+	foreach(l, sortclauses)
 	{
-		SortClause *sortcl = (SortClause *) lfirst(i);
+		SortClause *sortcl = (SortClause *) lfirst(l);
 		Node	   *sortkey;
 		PathKeyItem *pathkey;
 
@@ -1000,21 +996,21 @@ find_mergeclauses_for_pathkeys(Query *root,
 							   List *restrictinfos)
 {
 	List	   *mergeclauses = NIL;
-	List	   *i;
+	ListCell   *i;
 
 	/* make sure we have pathkeys cached in the clauses */
 	foreach(i, restrictinfos)
 	{
-		RestrictInfo *restrictinfo = lfirst(i);
+		RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i);
 
 		cache_mergeclause_pathkeys(root, restrictinfo);
 	}
 
 	foreach(i, pathkeys)
 	{
-		List	   *pathkey = lfirst(i);
+		List	   *pathkey = (List *) lfirst(i);
 		List	   *matched_restrictinfos = NIL;
-		List	   *j;
+		ListCell   *j;
 
 		/*
 		 * We can match a pathkey against either left or right side of any
@@ -1037,7 +1033,7 @@ find_mergeclauses_for_pathkeys(Query *root,
 		 */
 		foreach(j, restrictinfos)
 		{
-			RestrictInfo *restrictinfo = lfirst(j);
+			RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(j);
 
 			/*
 			 * We can compare canonical pathkey sublists by simple pointer
@@ -1093,11 +1089,11 @@ make_pathkeys_for_mergeclauses(Query *root,
 							   RelOptInfo *rel)
 {
 	List	   *pathkeys = NIL;
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, mergeclauses)
+	foreach(l, mergeclauses)
 	{
-		RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i);
+		RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
 		List	   *pathkey;
 
 		cache_mergeclause_pathkeys(root, restrictinfo);
@@ -1160,18 +1156,18 @@ int
 pathkeys_useful_for_merging(Query *root, RelOptInfo *rel, List *pathkeys)
 {
 	int			useful = 0;
-	List	   *i;
+	ListCell   *i;
 
 	foreach(i, pathkeys)
 	{
-		List	   *pathkey = lfirst(i);
+		List	   *pathkey = (List *) lfirst(i);
 		bool		matched = false;
-		List	   *j;
+		ListCell   *j;
 
 		foreach(j, rel->joininfo)
 		{
 			JoinInfo   *joininfo = (JoinInfo *) lfirst(j);
-			List	   *k;
+			ListCell   *k;
 
 			foreach(k, joininfo->jinfo_restrictinfo)
 			{
diff --git a/src/backend/optimizer/path/tidpath.c b/src/backend/optimizer/path/tidpath.c
index 1baccc1b3878d109380bae002e2029bb515e86db..dcb6566db04f222220eaa8831c96e9f132297795 100644
--- a/src/backend/optimizer/path/tidpath.c
+++ b/src/backend/optimizer/path/tidpath.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/path/tidpath.c,v 1.18 2003/11/29 19:51:50 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/tidpath.c,v 1.19 2004/05/26 04:41:22 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -33,7 +33,7 @@ static List *TidqualFromExpr(int varno, Expr *expr);
 static bool
 isEvaluable(int varno, Node *node)
 {
-	List	   *lst;
+	ListCell   *l;
 	FuncExpr   *expr;
 
 	if (IsA(node, Const))
@@ -51,9 +51,9 @@ isEvaluable(int varno, Node *node)
 	if (!is_funcclause(node))
 		return false;
 	expr = (FuncExpr *) node;
-	foreach(lst, expr->args)
+	foreach(l, expr->args)
 	{
-		if (!isEvaluable(varno, lfirst(lst)))
+		if (!isEvaluable(varno, lfirst(l)))
 			return false;
 	}
 
@@ -81,7 +81,7 @@ TidequalClause(int varno, OpExpr *node)
 		return rnode;
 	if (length(node->args) != 2)
 		return rnode;
-	arg1 = lfirst(node->args);
+	arg1 = linitial(node->args);
 	arg2 = lsecond(node->args);
 
 	arg = NULL;
@@ -156,8 +156,8 @@ static List *
 TidqualFromExpr(int varno, Expr *expr)
 {
 	List	   *rlst = NIL,
-			   *lst,
 			   *frtn;
+	ListCell   *l;
 	Node	   *node = (Node *) expr,
 			   *rnode;
 
@@ -169,9 +169,9 @@ TidqualFromExpr(int varno, Expr *expr)
 	}
 	else if (and_clause(node))
 	{
-		foreach(lst, ((BoolExpr *) expr)->args)
+		foreach(l, ((BoolExpr *) expr)->args)
 		{
-			node = lfirst(lst);
+			node = (Node *) lfirst(l);
 			rlst = TidqualFromExpr(varno, (Expr *) node);
 			if (rlst)
 				break;
@@ -179,9 +179,9 @@ TidqualFromExpr(int varno, Expr *expr)
 	}
 	else if (or_clause(node))
 	{
-		foreach(lst, ((BoolExpr *) expr)->args)
+		foreach(l, ((BoolExpr *) expr)->args)
 		{
-			node = lfirst(lst);
+			node = (Node *) lfirst(l);
 			frtn = TidqualFromExpr(varno, (Expr *) node);
 			if (frtn)
 				rlst = nconc(rlst, frtn);
@@ -200,8 +200,8 @@ TidqualFromExpr(int varno, Expr *expr)
 static List *
 TidqualFromRestrictinfo(Relids relids, List *restrictinfo)
 {
-	List	   *lst,
-			   *rlst = NIL;
+	ListCell   *l;
+	List	   *rlst = NIL;
 	int			varno;
 	Node	   *node;
 	Expr	   *expr;
@@ -209,9 +209,9 @@ TidqualFromRestrictinfo(Relids relids, List *restrictinfo)
 	if (bms_membership(relids) != BMS_SINGLETON)
 		return NIL;
 	varno = bms_singleton_member(relids);
-	foreach(lst, restrictinfo)
+	foreach(l, restrictinfo)
 	{
-		node = lfirst(lst);
+		node = (Node *) lfirst(l);
 		if (!IsA(node, RestrictInfo))
 			continue;
 		expr = ((RestrictInfo *) node)->clause;
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 1b4c9d478097b538b353384f919c92f4381283d2..efa7dd771225d6584ae7777df578e183a7379004 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.169 2004/04/25 18:23:56 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.170 2004/05/26 04:41:24 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -263,7 +263,7 @@ build_relation_tlist(RelOptInfo *rel)
 {
 	FastList	tlist;
 	int			resdomno = 1;
-	List	   *v;
+	ListCell   *v;
 
 	FastListInit(&tlist);
 	foreach(v, FastListValue(&rel->reltargetlist))
@@ -415,7 +415,7 @@ create_append_plan(Query *root, AppendPath *best_path)
 	Append	   *plan;
 	List	   *tlist = build_relation_tlist(best_path->path.parent);
 	List	   *subplans = NIL;
-	List	   *subpaths;
+	ListCell   *subpaths;
 
 	foreach(subpaths, best_path->subpaths)
 	{
@@ -505,7 +505,7 @@ create_unique_plan(Query *root, UniquePath *best_path)
 	List	   *newtlist;
 	int			nextresno;
 	bool		newitems;
-	List	   *l;
+	ListCell   *l;
 
 	subplan = create_plan(root, best_path->subpath);
 
@@ -544,7 +544,7 @@ create_unique_plan(Query *root, UniquePath *best_path)
 			break;
 		}
 	}
-	if (l == NIL)				/* fell out of loop? */
+	if (l == NULL)				/* fell out of loop? */
 		elog(ERROR, "could not find UniquePath in in_info_list");
 
 	/* set up to record positions of unique columns */
@@ -702,7 +702,7 @@ create_indexscan_plan(Query *root,
 	List	   *indxsubtype;
 	List	   *indxlossy;
 	FastList	indexids;
-	List	   *i;
+	ListCell   *l;
 	IndexScan  *scan_plan;
 
 	/* it should be a base rel... */
@@ -727,7 +727,7 @@ create_indexscan_plan(Query *root,
 		 */
 		Assert(length(best_path->indexclauses) == 1);
 		scan_clauses = set_ptrUnion(scan_clauses,
-									(List *) lfirst(best_path->indexclauses));
+									(List *) linitial(best_path->indexclauses));
 	}
 
 	/* Reduce RestrictInfo list to bare expressions */
@@ -738,9 +738,9 @@ create_indexscan_plan(Query *root,
 
 	/* Build list of index OIDs */
 	FastListInit(&indexids);
-	foreach(i, best_path->indexinfo)
+	foreach(l, best_path->indexinfo)
 	{
-		IndexOptInfo *index = (IndexOptInfo *) lfirst(i);
+		IndexOptInfo *index = (IndexOptInfo *) lfirst(l);
 
 		FastAppendo(&indexids, index->indexoid);
 	}
@@ -750,9 +750,9 @@ create_indexscan_plan(Query *root,
 	 * executor as indxqualorig
 	 */
 	stripped_indxquals = NIL;
-	foreach(i, indxquals)
+	foreach(l, indxquals)
 	{
-		List   *andlist = (List *) lfirst(i);
+		List   *andlist = (List *) lfirst(l);
 
 		stripped_indxquals = lappend(stripped_indxquals,
 									 get_actual_clauses(andlist));
@@ -785,7 +785,7 @@ create_indexscan_plan(Query *root,
 		 * behavior.
 		 */
 		Assert(stripped_indxquals != NIL);
-		qpqual = set_difference(scan_clauses, lfirst(stripped_indxquals));
+		qpqual = set_difference(scan_clauses, linitial(stripped_indxquals));
 	}
 
 	/*
@@ -955,7 +955,7 @@ create_nestloop_plan(Query *root,
 			joinrestrictclauses =
 				select_nonredundant_join_clauses(root,
 												 joinrestrictclauses,
-												 lfirst(indexclauses),
+												 linitial(indexclauses),
 												 best_path->jointype);
 		}
 	}
@@ -1182,17 +1182,17 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path,
 {
 	Relids		baserelids = index_path->path.parent->relids;
 	int			baserelid = index_path->path.parent->relid;
-	List	   *ixinfo = index_path->indexinfo;
-	List	   *i;
+	List	   *index_info = index_path->indexinfo;
+	ListCell   *iq, *ii;
 
 	*fixed_indexquals = NIL;
 	*indxstrategy = NIL;
 	*indxsubtype = NIL;
 	*indxlossy = NIL;
-	foreach(i, indexquals)
+	forboth(iq, indexquals, ii, index_info)
 	{
-		List	   *indexqual = lfirst(i);
-		IndexOptInfo *index = (IndexOptInfo *) lfirst(ixinfo);
+		List	   *indexqual = (List *) lfirst(iq);
+		IndexOptInfo *index = (IndexOptInfo *) lfirst(ii);
 		List	   *fixed_qual;
 		List	   *strategy;
 		List	   *subtype;
@@ -1204,8 +1204,6 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path,
 		*indxstrategy = lappend(*indxstrategy, strategy);
 		*indxsubtype = lappend(*indxsubtype, subtype);
 		*indxlossy = lappend(*indxlossy, lossy);
-
-		ixinfo = lnext(ixinfo);
 	}
 }
 
@@ -1232,15 +1230,15 @@ fix_indxqual_sublist(List *indexqual,
 					 List **subtype,
 					 List **lossy)
 {
-	List	   *i;
+	ListCell   *l;
 
 	*fixed_quals = NIL;
 	*strategy = NIL;
 	*subtype = NIL;
 	*lossy = NIL;
-	foreach(i, indexqual)
+	foreach(l, indexqual)
 	{
-		RestrictInfo *rinfo = (RestrictInfo *) lfirst(i);
+		RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
 		OpExpr	   *clause;
 		OpExpr	   *newclause;
 		Oid			opclass;
@@ -1250,8 +1248,7 @@ fix_indxqual_sublist(List *indexqual,
 
 		Assert(IsA(rinfo, RestrictInfo));
 		clause = (OpExpr *) rinfo->clause;
-		if (!IsA(clause, OpExpr) ||
-			length(clause->args) != 2)
+		if (!IsA(clause, OpExpr) || length(clause->args) != 2)
 			elog(ERROR, "indexqual clause is not binary opclause");
 
 		/*
@@ -1275,7 +1272,7 @@ fix_indxqual_sublist(List *indexqual,
 		 * Now, determine which index attribute this is, change the
 		 * indexkey operand as needed, and get the index opclass.
 		 */
-		lfirst(newclause->args) = fix_indxqual_operand(lfirst(newclause->args),
+		linitial(newclause->args) = fix_indxqual_operand(linitial(newclause->args),
 													   baserelid,
 													   index,
 													   &opclass);
@@ -1309,7 +1306,7 @@ fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index,
 	 */
 	Var		   *result;
 	int			pos;
-	List	   *indexprs;
+	ListCell   *indexpr_item;
 
 	/*
 	 * Remove any binary-compatible relabeling of the indexkey
@@ -1340,29 +1337,29 @@ fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index,
 	}
 
 	/* Try to match against index expressions */
-	indexprs = index->indexprs;
+	indexpr_item = list_head(index->indexprs);
 	for (pos = 0; pos < index->ncolumns; pos++)
 	{
 		if (index->indexkeys[pos] == 0)
 		{
 			Node	   *indexkey;
 
-			if (indexprs == NIL)
+			if (indexpr_item == NULL)
 				elog(ERROR, "too few entries in indexprs list");
-			indexkey = (Node *) lfirst(indexprs);
+			indexkey = (Node *) lfirst(indexpr_item);
 			if (indexkey && IsA(indexkey, RelabelType))
 				indexkey = (Node *) ((RelabelType *) indexkey)->arg;
 			if (equal(node, indexkey))
 			{
 				/* Found a match */
 				result = makeVar(baserelid, pos + 1,
-								 exprType(lfirst(indexprs)), -1,
+								 exprType(lfirst(indexpr_item)), -1,
 								 0);
 				/* return the correct opclass, too */
 				*opclass = index->classlist[pos];
 				return (Node *) result;
 			}
-			indexprs = lnext(indexprs);
+			indexpr_item = lnext(indexpr_item);
 		}
 	}
 
@@ -1383,11 +1380,11 @@ static List *
 get_switched_clauses(List *clauses, Relids outerrelids)
 {
 	List	   *t_list = NIL;
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, clauses)
+	foreach(l, clauses)
 	{
-		RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(i);
+		RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
 		OpExpr	   *clause = (OpExpr *) restrictinfo->clause;
 
 		Assert(is_opclause(clause));
@@ -1432,7 +1429,7 @@ order_qual_clauses(Query *root, List *clauses)
 {
 	FastList	nosubplans;
 	FastList	withsubplans;
-	List	   *l;
+	ListCell   *l;
 
 	/* No need to work hard if the query is subselect-free */
 	if (!root->hasSubLinks)
@@ -1442,7 +1439,7 @@ order_qual_clauses(Query *root, List *clauses)
 	FastListInit(&withsubplans);
 	foreach(l, clauses)
 	{
-		Node	   *clause = lfirst(l);
+		Node	   *clause = (Node *) lfirst(l);
 
 		if (contain_subplans(clause))
 			FastAppend(&withsubplans, clause);
@@ -1632,7 +1629,7 @@ make_append(List *appendplans, bool isTarget, List *tlist)
 {
 	Append	   *node = makeNode(Append);
 	Plan	   *plan = &node->plan;
-	List	   *subnode;
+	ListCell   *subnode;
 
 	/*
 	 * Compute cost as sum of subplan costs.  We charge nothing extra for
@@ -1647,7 +1644,7 @@ make_append(List *appendplans, bool isTarget, List *tlist)
 	{
 		Plan	   *subplan = (Plan *) lfirst(subnode);
 
-		if (subnode == appendplans)		/* first node? */
+		if (subnode == list_head(appendplans))		/* first node? */
 			plan->startup_cost = subplan->startup_cost;
 		plan->total_cost += subplan->total_cost;
 		plan->plan_rows += subplan->plan_rows;
@@ -1837,7 +1834,7 @@ static Sort *
 make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
 {
 	List	   *tlist = lefttree->targetlist;
-	List	   *i;
+	ListCell   *i;
 	int			numsortkeys;
 	AttrNumber *sortColIdx;
 	Oid		   *sortOperators;
@@ -1854,7 +1851,7 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
 		List	   *keysublist = (List *) lfirst(i);
 		PathKeyItem *pathkey = NULL;
 		Resdom	   *resdom = NULL;
-		List	   *j;
+		ListCell   *j;
 
 		/*
 		 * We can sort by any one of the sort key items listed in this
@@ -1870,7 +1867,7 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
 		 */
 		foreach(j, keysublist)
 		{
-			pathkey = lfirst(j);
+			pathkey = (PathKeyItem *) lfirst(j);
 			Assert(IsA(pathkey, PathKeyItem));
 			resdom = tlist_member(pathkey->key, tlist);
 			if (resdom)
@@ -1881,10 +1878,10 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
 			/* No matching Var; look for a computable expression */
 			foreach(j, keysublist)
 			{
-				List   *exprvars;
-				List   *k;
+				List		*exprvars;
+				ListCell	*k;
 
-				pathkey = lfirst(j);
+				pathkey = (PathKeyItem *) lfirst(j);
 				exprvars = pull_var_clause(pathkey->key, false);
 				foreach(k, exprvars)
 				{
@@ -1948,7 +1945,7 @@ Sort *
 make_sort_from_sortclauses(Query *root, List *sortcls, Plan *lefttree)
 {
 	List	   *sub_tlist = lefttree->targetlist;
-	List	   *i;
+	ListCell   *l;
 	int			numsortkeys;
 	AttrNumber *sortColIdx;
 	Oid		   *sortOperators;
@@ -1960,9 +1957,9 @@ make_sort_from_sortclauses(Query *root, List *sortcls, Plan *lefttree)
 
 	numsortkeys = 0;
 
-	foreach(i, sortcls)
+	foreach(l, sortcls)
 	{
-		SortClause *sortcl = (SortClause *) lfirst(i);
+		SortClause *sortcl = (SortClause *) lfirst(l);
 		TargetEntry *tle = get_sortgroupclause_tle(sortcl, sub_tlist);
 
 		/*
@@ -2001,7 +1998,7 @@ make_sort_from_groupcols(Query *root,
 {
 	List	   *sub_tlist = lefttree->targetlist;
 	int			grpno = 0;
-	List	   *i;
+	ListCell   *l;
 	int			numsortkeys;
 	AttrNumber *sortColIdx;
 	Oid		   *sortOperators;
@@ -2013,9 +2010,9 @@ make_sort_from_groupcols(Query *root,
 
 	numsortkeys = 0;
 
-	foreach(i, groupcls)
+	foreach(l, groupcls)
 	{
-		GroupClause *grpcl = (GroupClause *) lfirst(i);
+		GroupClause *grpcl = (GroupClause *) lfirst(l);
 		TargetEntry *tle = get_tle_by_resno(sub_tlist, grpColIdx[grpno]);
 
 		/*
@@ -2213,7 +2210,7 @@ make_unique(Plan *lefttree, List *distinctList)
 	int			numCols = length(distinctList);
 	int			keyno = 0;
 	AttrNumber *uniqColIdx;
-	List	   *slitem;
+	ListCell   *slitem;
 
 	copy_plan_costsize(plan, lefttree);
 
@@ -2270,7 +2267,7 @@ make_setop(SetOpCmd cmd, Plan *lefttree,
 	int			numCols = length(distinctList);
 	int			keyno = 0;
 	AttrNumber *dupColIdx;
-	List	   *slitem;
+	ListCell   *slitem;
 
 	copy_plan_costsize(plan, lefttree);
 
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 46fde263456e935f871f8af7de89dc3251e0dbbc..f8a4bfaaac48504f1e0e7e9f6418840c9ab0fc53 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.98 2004/02/27 21:42:00 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/initsplan.c,v 1.99 2004/05/26 04:41:24 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -81,7 +81,7 @@ add_base_rels_to_query(Query *root, Node *jtnode)
 	else if (IsA(jtnode, FromExpr))
 	{
 		FromExpr   *f = (FromExpr *) jtnode;
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, f->fromlist)
 			add_base_rels_to_query(root, lfirst(l));
@@ -135,7 +135,7 @@ build_base_rel_tlists(Query *root, List *final_tlist)
 static void
 add_vars_to_targetlist(Query *root, List *vars, Relids where_needed)
 {
-	List	   *temp;
+	ListCell   *temp;
 
 	Assert(!bms_is_empty(where_needed));
 
@@ -205,8 +205,7 @@ distribute_quals_to_rels(Query *root, Node *jtnode)
 	else if (IsA(jtnode, FromExpr))
 	{
 		FromExpr   *f = (FromExpr *) jtnode;
-		List	   *l;
-		List	   *qual;
+		ListCell   *l;
 
 		/*
 		 * First, recurse to handle child joins.
@@ -222,8 +221,8 @@ distribute_quals_to_rels(Query *root, Node *jtnode)
 		 * Now process the top-level quals.  These are always marked as
 		 * "pushed down", since they clearly didn't come from a JOIN expr.
 		 */
-		foreach(qual, (List *) f->quals)
-			distribute_qual_to_rels(root, (Node *) lfirst(qual),
+		foreach(l, (List *) f->quals)
+			distribute_qual_to_rels(root, (Node *) lfirst(l),
 									true, false, NULL, result);
 	}
 	else if (IsA(jtnode, JoinExpr))
@@ -233,7 +232,7 @@ distribute_quals_to_rels(Query *root, Node *jtnode)
 					rightids,
 					nonnullable_rels,
 					nullable_rels;
-		List	   *qual;
+		ListCell   *qual;
 
 		/*
 		 * Order of operations here is subtle and critical.  First we
@@ -636,7 +635,7 @@ process_implied_equality(Query *root,
 	BMS_Membership membership;
 	RelOptInfo *rel1;
 	List	   *restrictlist;
-	List	   *itm;
+	ListCell   *itm;
 	Oid			ltype,
 				rtype;
 	Operator	eq_operator;
@@ -803,7 +802,7 @@ qual_is_redundant(Query *root,
 	Node	   *newleft;
 	Node	   *newright;
 	List	   *oldquals;
-	List	   *olditem;
+	ListCell   *olditem;
 	List	   *equalexprs;
 	bool		someadded;
 
@@ -860,7 +859,7 @@ qual_is_redundant(Query *root,
 	{
 		someadded = false;
 		/* cannot use foreach here because of possible lremove */
-		olditem = oldquals;
+		olditem = list_head(oldquals);
 		while (olditem)
 		{
 			RestrictInfo *oldrinfo = (RestrictInfo *) lfirst(olditem);
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index e094620d620afde730c6f054c17794cbf4211dd6..7b5d44c732bcb079b757dd27fe21ceff4da4cd6c 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.169 2004/05/11 02:21:37 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.170 2004/05/26 04:41:24 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -174,6 +174,7 @@ subquery_planner(Query *parse, double tuple_fraction)
 	Plan	   *plan;
 	List	   *newHaving;
 	List	   *lst;
+	ListCell   *l;
 
 	/* Set up for a new level of subquery */
 	PlannerQueryLevel++;
@@ -206,9 +207,9 @@ subquery_planner(Query *parse, double tuple_fraction)
 	 */
 	parse->hasJoinRTEs = false;
 	hasOuterJoins = false;
-	foreach(lst, parse->rtable)
+	foreach(l, parse->rtable)
 	{
-		RangeTblEntry *rte = (RangeTblEntry *) lfirst(lst);
+		RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
 
 		if (rte->rtekind == RTE_JOIN)
 		{
@@ -244,9 +245,9 @@ subquery_planner(Query *parse, double tuple_fraction)
 							  EXPRKIND_ININFO);
 
 	/* Also need to preprocess expressions for function RTEs */
-	foreach(lst, parse->rtable)
+	foreach(l, parse->rtable)
 	{
-		RangeTblEntry *rte = (RangeTblEntry *) lfirst(lst);
+		RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
 
 		if (rte->rtekind == RTE_FUNCTION)
 			rte->funcexpr = preprocess_expression(parse, rte->funcexpr,
@@ -271,9 +272,9 @@ subquery_planner(Query *parse, double tuple_fraction)
 	 * declared as Node *.
 	 */
 	newHaving = NIL;
-	foreach(lst, (List *) parse->havingQual)
+	foreach(l, (List *) parse->havingQual)
 	{
-		Node	   *havingclause = (Node *) lfirst(lst);
+		Node	   *havingclause = (Node *) lfirst(l);
 
 		if (contain_agg_clause(havingclause))
 			newHaving = lappend(newHaving, havingclause);
@@ -337,9 +338,9 @@ subquery_planner(Query *parse, double tuple_fraction)
 		 */
 		plan->initPlan = PlannerInitPlan;
 
-		foreach(lst, plan->initPlan)
+		foreach(l, plan->initPlan)
 		{
-			SubPlan    *initplan = (SubPlan *) lfirst(lst);
+			SubPlan    *initplan = (SubPlan *) lfirst(l);
 
 			plan->extParam = bms_add_members(plan->extParam,
 											 initplan->plan->extParam);
@@ -445,7 +446,7 @@ preprocess_qual_conditions(Query *parse, Node *jtnode)
 	else if (IsA(jtnode, FromExpr))
 	{
 		FromExpr   *f = (FromExpr *) jtnode;
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, f->fromlist)
 			preprocess_qual_conditions(parse, lfirst(l));
@@ -495,7 +496,7 @@ inheritance_planner(Query *parse, List *inheritlist)
 	int			mainrtlength = length(parse->rtable);
 	List	   *subplans = NIL;
 	List	   *tlist = NIL;
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, inheritlist)
 	{
@@ -524,10 +525,9 @@ inheritance_planner(Query *parse, List *inheritlist)
 		subrtlength = length(subquery->rtable);
 		if (subrtlength > mainrtlength)
 		{
-			List	   *subrt = subquery->rtable;
+			List	   *subrt;
 
-			while (mainrtlength-- > 0)	/* wish we had nthcdr() */
-				subrt = lnext(subrt);
+			subrt = list_copy_tail(subquery->rtable, mainrtlength);
 			parse->rtable = nconc(parse->rtable, subrt);
 			mainrtlength = subrtlength;
 		}
@@ -650,7 +650,7 @@ grouping_planner(Query *parse, double tuple_fraction)
 		 */
 		if (parse->rowMarks)
 		{
-			List	   *l;
+			ListCell   *l;
 
 			/*
 			 * We've got trouble if the FOR UPDATE appears inside
@@ -1328,7 +1328,7 @@ grouping_planner(Query *parse, double tuple_fraction)
 static bool
 hash_safe_grouping(Query *parse)
 {
-	List	   *gl;
+	ListCell   *gl;
 
 	foreach(gl, parse->groupClause)
 	{
@@ -1435,17 +1435,17 @@ make_subplanTargetList(Query *parse,
 	{
 		int			keyno = 0;
 		AttrNumber *grpColIdx;
-		List	   *gl;
+		ListCell   *gl;
 
 		grpColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
 		*groupColIdx = grpColIdx;
 
 		foreach(gl, parse->groupClause)
 		{
-			GroupClause *grpcl = (GroupClause *) lfirst(gl);
-			Node	   *groupexpr = get_sortgroupclause_expr(grpcl, tlist);
-			TargetEntry *te = NULL;
-			List	   *sl;
+			GroupClause		*grpcl = (GroupClause *) lfirst(gl);
+			Node			*groupexpr = get_sortgroupclause_expr(grpcl, tlist);
+			TargetEntry		*te = NULL;
+			ListCell		*sl;
 
 			/* Find or make a matching sub_tlist entry */
 			foreach(sl, sub_tlist)
@@ -1489,7 +1489,7 @@ locate_grouping_columns(Query *parse,
 						AttrNumber *groupColIdx)
 {
 	int			keyno = 0;
-	List	   *gl;
+	ListCell   *gl;
 
 	/*
 	 * No work unless grouping.
@@ -1503,10 +1503,10 @@ locate_grouping_columns(Query *parse,
 
 	foreach(gl, parse->groupClause)
 	{
-		GroupClause *grpcl = (GroupClause *) lfirst(gl);
-		Node	   *groupexpr = get_sortgroupclause_expr(grpcl, tlist);
-		TargetEntry *te = NULL;
-		List	   *sl;
+		GroupClause		*grpcl = (GroupClause *) lfirst(gl);
+		Node			*groupexpr = get_sortgroupclause_expr(grpcl, tlist);
+		TargetEntry		*te = NULL;
+		ListCell		*sl;
 
 		foreach(sl, sub_tlist)
 		{
@@ -1534,7 +1534,8 @@ locate_grouping_columns(Query *parse,
 static List *
 postprocess_setop_tlist(List *new_tlist, List *orig_tlist)
 {
-	List	   *l;
+	ListCell   *l;
+	ListCell   *orig_tlist_item = list_head(orig_tlist);
 
 	foreach(l, new_tlist)
 	{
@@ -1545,16 +1546,16 @@ postprocess_setop_tlist(List *new_tlist, List *orig_tlist)
 		if (new_tle->resdom->resjunk)
 			continue;
 
-		Assert(orig_tlist != NIL);
-		orig_tle = (TargetEntry *) lfirst(orig_tlist);
-		orig_tlist = lnext(orig_tlist);
+		Assert(orig_tlist_item != NULL);
+		orig_tle = (TargetEntry *) lfirst(orig_tlist_item);
+		orig_tlist_item = lnext(orig_tlist_item);
 		if (orig_tle->resdom->resjunk)	/* should not happen */
 			elog(ERROR, "resjunk output columns are not implemented");
 		Assert(new_tle->resdom->resno == orig_tle->resdom->resno);
 		Assert(new_tle->resdom->restype == orig_tle->resdom->restype);
 		new_tle->resdom->ressortgroupref = orig_tle->resdom->ressortgroupref;
 	}
-	if (orig_tlist != NIL)
+	if (orig_tlist_item != NULL)
 		elog(ERROR, "resjunk output columns are not implemented");
 	return new_tlist;
 }
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 84b2aa82805e26120b0f1c036f6bdce8c4aeb76c..b8fe70e9350d05e3db47ef51c3182135fe79f93a 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.101 2004/05/11 13:15:15 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.102 2004/05/26 04:41:24 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -84,7 +84,7 @@ static void set_sa_opfuncid(ScalarArrayOpExpr *opexpr);
 void
 set_plan_references(Plan *plan, List *rtable)
 {
-	List	   *pl;
+	ListCell *l;
 
 	if (plan == NULL)
 		return;
@@ -213,15 +213,14 @@ set_plan_references(Plan *plan, List *rtable)
 			fix_expr_references(plan, ((Result *) plan)->resconstantqual);
 			break;
 		case T_Append:
-
 			/*
 			 * Append, like Sort et al, doesn't actually evaluate its
-			 * targetlist or quals, and we haven't bothered to give it its
-			 * own tlist copy.	So, don't fix targetlist/qual. But do
-			 * recurse into child plans.
+			 * targetlist or quals, and we haven't bothered to give it
+			 * its own tlist copy. So, don't fix targetlist/qual. But
+			 * do recurse into child plans.
 			 */
-			foreach(pl, ((Append *) plan)->appendplans)
-				set_plan_references((Plan *) lfirst(pl), rtable);
+			foreach(l, ((Append *) plan)->appendplans)
+				set_plan_references((Plan *) lfirst(l), rtable);
 			break;
 		default:
 			elog(ERROR, "unrecognized node type: %d",
@@ -242,9 +241,9 @@ set_plan_references(Plan *plan, List *rtable)
 	set_plan_references(plan->lefttree, rtable);
 	set_plan_references(plan->righttree, rtable);
 
-	foreach(pl, plan->initPlan)
+	foreach(l, plan->initPlan)
 	{
-		SubPlan    *sp = (SubPlan *) lfirst(pl);
+		SubPlan    *sp = (SubPlan *) lfirst(l);
 
 		Assert(IsA(sp, SubPlan));
 		set_plan_references(sp->plan, sp->rtable);
@@ -440,8 +439,8 @@ set_uppernode_references(Plan *plan, Index subvarno)
 {
 	Plan	   *subplan = plan->lefttree;
 	List	   *subplan_targetlist,
-			   *output_targetlist,
-			   *l;
+			   *output_targetlist;
+	ListCell   *l;
 	bool		tlist_has_non_vars;
 
 	if (subplan != NULL)
@@ -483,7 +482,7 @@ set_uppernode_references(Plan *plan, Index subvarno)
 static bool
 targetlist_has_non_vars(List *tlist)
 {
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, tlist)
 	{
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index af33da1184e8d74d45ca3434262ea8d42cceee75..9245da803e2cb2b875aeb1ad0542449be42e2eb3 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.89 2004/05/11 13:15:15 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.90 2004/05/26 04:41:24 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -101,7 +101,7 @@ static Param *
 replace_outer_var(Var *var)
 {
 	Param	   *retval;
-	List	   *ppl;
+	ListCell   *ppl;
 	PlannerParamItem *pitem;
 	Index		abslevel;
 	int			i;
@@ -250,7 +250,6 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
 	Plan	   *plan;
 	Bitmapset  *tmpset;
 	int			paramid;
-	List	   *lst;
 	Node	   *result;
 
 	/*
@@ -348,7 +347,7 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
 	}
 	else if (node->parParam == NIL && slink->subLinkType == EXPR_SUBLINK)
 	{
-		TargetEntry *te = lfirst(plan->targetlist);
+		TargetEntry *te = linitial(plan->targetlist);
 		Param	   *prm;
 
 		Assert(!te->resdom->resjunk);
@@ -359,7 +358,7 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
 	}
 	else if (node->parParam == NIL && slink->subLinkType == ARRAY_SUBLINK)
 	{
-		TargetEntry *te = lfirst(plan->targetlist);
+		TargetEntry *te = linitial(plan->targetlist);
 		Oid			arraytype;
 		Param	   *prm;
 
@@ -395,11 +394,12 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
 			result = (Node *) (node->useOr ? make_orclause(exprs) :
 							   make_andclause(exprs));
 		else
-			result = (Node *) lfirst(exprs);
+			result = (Node *) linitial(exprs);
 	}
 	else
 	{
 		List	   *args;
+		ListCell   *l;
 
 		/*
 		 * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types
@@ -471,9 +471,9 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
 		 * Make node->args from parParam.
 		 */
 		args = NIL;
-		foreach(lst, node->parParam)
+		foreach(l, node->parParam)
 		{
-			PlannerParamItem *pitem = nth(lfirsti(lst), PlannerParamList);
+			PlannerParamItem *pitem = nth(lfirsti(l), PlannerParamList);
 
 			/*
 			 * The Var or Aggref has already been adjusted to have the
@@ -509,15 +509,17 @@ convert_sublink_opers(List *lefthand, List *operOids,
 					  List **righthandIds)
 {
 	List	   *result = NIL;
-	List	   *lst;
+	ListCell   *l, *lefthand_item, *tlist_item;
 
 	*righthandIds = NIL;
+	lefthand_item = list_head(lefthand);
+	tlist_item = list_head(targetlist);
 
-	foreach(lst, operOids)
+	foreach(l, operOids)
 	{
-		Oid			opid = lfirsto(lst);
-		Node	   *leftop = lfirst(lefthand);
-		TargetEntry *te = lfirst(targetlist);
+		Oid			opid = lfirsto(l);
+		Node	   *leftop = (Node *) lfirst(lefthand_item);
+		TargetEntry *te = (TargetEntry *) lfirst(tlist_item);
 		Node	   *rightop;
 		Operator	tup;
 
@@ -574,8 +576,8 @@ convert_sublink_opers(List *lefthand, List *operOids,
 
 		ReleaseSysCache(tup);
 
-		lefthand = lnext(lefthand);
-		targetlist = lnext(targetlist);
+		lefthand_item = lnext(lefthand_item);
+		tlist_item = lnext(tlist_item);
 	}
 
 	return result;
@@ -591,7 +593,7 @@ static bool
 subplan_is_hashable(SubLink *slink, SubPlan *node)
 {
 	double		subquery_size;
-	List	   *opids;
+	ListCell   *l;
 
 	/*
 	 * The sublink type must be "= ANY" --- that is, an IN operator. (We
@@ -602,7 +604,7 @@ subplan_is_hashable(SubLink *slink, SubPlan *node)
 	if (slink->subLinkType != ANY_SUBLINK)
 		return false;
 	if (length(slink->operName) != 1 ||
-		strcmp(strVal(lfirst(slink->operName)), "=") != 0)
+		strcmp(strVal(linitial(slink->operName)), "=") != 0)
 		return false;
 
 	/*
@@ -636,9 +638,9 @@ subplan_is_hashable(SubLink *slink, SubPlan *node)
 	 * different sets of operators with the hash table, but there is no
 	 * obvious usefulness to that at present.)
 	 */
-	foreach(opids, slink->operOids)
+	foreach(l, slink->operOids)
 	{
-		Oid			opid = lfirsto(opids);
+		Oid			opid = lfirsto(l);
 		HeapTuple	tup;
 		Form_pg_operator optup;
 
@@ -690,7 +692,7 @@ convert_IN_to_join(Query *parse, SubLink *sublink)
 	if (sublink->subLinkType != ANY_SUBLINK)
 		return NULL;
 	if (length(sublink->operName) != 1 ||
-		strcmp(strVal(lfirst(sublink->operName)), "=") != 0)
+		strcmp(strVal(linitial(sublink->operName)), "=") != 0)
 		return NULL;
 
 	/*
@@ -859,8 +861,8 @@ process_sublinks_mutator(Node *node, bool *isTopQual)
 	 */
 	if (and_clause(node))
 	{
-		List   *newargs = NIL;
-		List   *l;
+		List		*newargs = NIL;
+		ListCell	*l;
 
 		/* Still at qual top-level */
 		locTopQual = *isTopQual;
@@ -884,8 +886,8 @@ process_sublinks_mutator(Node *node, bool *isTopQual)
 
 	if (or_clause(node))
 	{
-		List   *newargs = NIL;
-		List   *l;
+		List		*newargs = NIL;
+		ListCell	*l;
 
 		foreach(l, ((BoolExpr *) node)->args)
 		{
@@ -918,7 +920,7 @@ SS_finalize_plan(Plan *plan, List *rtable)
 	Bitmapset  *outer_params = NULL;
 	Bitmapset  *valid_params = NULL;
 	int			paramid;
-	List	   *lst;
+	ListCell   *l;
 
 	/*
 	 * First, scan the param list to discover the sets of params that are
@@ -926,9 +928,9 @@ SS_finalize_plan(Plan *plan, List *rtable)
 	 * this once to save time in the per-plan recursion steps.
 	 */
 	paramid = 0;
-	foreach(lst, PlannerParamList)
+	foreach(l, PlannerParamList)
 	{
-		PlannerParamItem *pitem = (PlannerParamItem *) lfirst(lst);
+		PlannerParamItem *pitem = (PlannerParamItem *) lfirst(l);
 
 		if (pitem->abslevel < PlannerQueryLevel)
 		{
@@ -966,7 +968,6 @@ finalize_plan(Plan *plan, List *rtable,
 			  Bitmapset *outer_params, Bitmapset *valid_params)
 {
 	finalize_primnode_context context;
-	List	   *lst;
 
 	if (plan == NULL)
 		return NULL;
@@ -1033,14 +1034,18 @@ finalize_plan(Plan *plan, List *rtable,
 			break;
 
 		case T_Append:
-			foreach(lst, ((Append *) plan)->appendplans)
 			{
-				context.paramids =
-					bms_add_members(context.paramids,
-									finalize_plan((Plan *) lfirst(lst),
-												  rtable,
-												  outer_params,
-												  valid_params));
+				ListCell *l;
+
+				foreach(l, ((Append *) plan)->appendplans)
+				{
+					context.paramids =
+						bms_add_members(context.paramids,
+										finalize_plan((Plan *) lfirst(l),
+													  rtable,
+													  outer_params,
+													  valid_params));
+				}
 			}
 			break;
 
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 0ddf1ccd67f2b8dbd1188b5e5d44fd7e0ce66d96..f916d54602d9b9aff14f8df78e006b415d18cc51 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -16,7 +16,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.17 2004/05/10 22:44:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.18 2004/05/26 04:41:26 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -97,11 +97,11 @@ pull_up_IN_clauses(Query *parse, Node *node)
 	if (and_clause(node))
 	{
 		List	   *newclauses = NIL;
-		List	   *oldclauses;
+		ListCell   *l;
 
-		foreach(oldclauses, ((BoolExpr *) node)->args)
+		foreach(l, ((BoolExpr *) node)->args)
 		{
-			Node	   *oldclause = lfirst(oldclauses);
+			Node	   *oldclause = (Node *) lfirst(l);
 
 			newclauses = lappend(newclauses,
 								 pull_up_IN_clauses(parse,
@@ -162,7 +162,7 @@ pull_up_subqueries(Query *parse, Node *jtnode, bool below_outer_join)
 		{
 			int			rtoffset;
 			List	   *subtlist;
-			List	   *rt;
+			ListCell   *rt;
 
 			/*
 			 * Need a modifiable copy of the subquery to hack on.  Even if
@@ -314,7 +314,7 @@ pull_up_subqueries(Query *parse, Node *jtnode, bool below_outer_join)
 	else if (IsA(jtnode, FromExpr))
 	{
 		FromExpr   *f = (FromExpr *) jtnode;
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, f->fromlist)
 			lfirst(l) = pull_up_subqueries(parse, lfirst(l),
@@ -447,7 +447,7 @@ is_simple_subquery(Query *subquery)
 static bool
 has_nullable_targetlist(Query *subquery)
 {
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, subquery->targetList)
 	{
@@ -488,7 +488,7 @@ resolvenew_in_jointree(Node *jtnode, int varno,
 	else if (IsA(jtnode, FromExpr))
 	{
 		FromExpr   *f = (FromExpr *) jtnode;
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, f->fromlist)
 			resolvenew_in_jointree(lfirst(l), varno, rte, subtlist);
@@ -588,7 +588,7 @@ reduce_outer_joins_pass1(Node *jtnode)
 	else if (IsA(jtnode, FromExpr))
 	{
 		FromExpr   *f = (FromExpr *) jtnode;
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, f->fromlist)
 		{
@@ -653,8 +653,8 @@ reduce_outer_joins_pass2(Node *jtnode,
 	else if (IsA(jtnode, FromExpr))
 	{
 		FromExpr   *f = (FromExpr *) jtnode;
-		List	   *l;
-		List	   *s;
+		ListCell   *l;
+		ListCell   *s;
 		Relids		pass_nonnullable;
 
 		/* Scan quals to see if we can add any nonnullability constraints */
@@ -662,15 +662,14 @@ reduce_outer_joins_pass2(Node *jtnode,
 		pass_nonnullable = bms_add_members(pass_nonnullable,
 										   nonnullable_rels);
 		/* And recurse --- but only into interesting subtrees */
-		s = state->sub_states;
-		foreach(l, f->fromlist)
+		Assert(length(f->fromlist) == length(state->sub_states));
+		forboth(l, f->fromlist, s, state->sub_states)
 		{
 			reduce_outer_joins_state *sub_state = lfirst(s);
 
 			if (sub_state->contains_outer)
 				reduce_outer_joins_pass2(lfirst(l), sub_state, parse,
 										 pass_nonnullable);
-			s = lnext(s);
 		}
 		bms_free(pass_nonnullable);
 	}
@@ -679,7 +678,7 @@ reduce_outer_joins_pass2(Node *jtnode,
 		JoinExpr   *j = (JoinExpr *) jtnode;
 		int			rtindex = j->rtindex;
 		JoinType	jointype = j->jointype;
-		reduce_outer_joins_state *left_state = lfirst(state->sub_states);
+		reduce_outer_joins_state *left_state = linitial(state->sub_states);
 		reduce_outer_joins_state *right_state = lsecond(state->sub_states);
 
 		/* Can we simplify this join? */
@@ -798,7 +797,7 @@ find_nonnullable_rels(Node *node, bool top_level)
 	}
 	else if (IsA(node, List))
 	{
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, (List *) node)
 		{
@@ -898,7 +897,7 @@ simplify_jointree(Query *parse, Node *jtnode)
 	{
 		FromExpr   *f = (FromExpr *) jtnode;
 		List	   *newlist = NIL;
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, f->fromlist)
 		{
@@ -918,7 +917,16 @@ simplify_jointree(Query *parse, Node *jtnode)
 				 */
 				FromExpr   *subf = (FromExpr *) child;
 				int			childlen = length(subf->fromlist);
-				int			myothers = length(newlist) + length(lnext(l));
+				int			myothers;
+				ListCell   *l2;
+
+				/*
+				 * XXX: This is a quick hack, not sure of the proper
+				 * fix.
+				 */
+				myothers = length(newlist);
+				for_each_cell(l2, lnext(l))
+					myothers++;
 
 				if (childlen <= 1 ||
 					(childlen + myothers) <= from_collapse_limit)
@@ -1022,7 +1030,7 @@ simplify_jointree(Query *parse, Node *jtnode)
 static void
 fix_in_clause_relids(List *in_info_list, int varno, Relids subrelids)
 {
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, in_info_list)
 	{
@@ -1060,7 +1068,7 @@ get_relids_in_jointree(Node *jtnode)
 	else if (IsA(jtnode, FromExpr))
 	{
 		FromExpr   *f = (FromExpr *) jtnode;
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, f->fromlist)
 		{
@@ -1119,7 +1127,7 @@ find_jointree_node_for_rel(Node *jtnode, int relid)
 	else if (IsA(jtnode, FromExpr))
 	{
 		FromExpr   *f = (FromExpr *) jtnode;
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, f->fromlist)
 		{
diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c
index ac107aade61ad77a2e89137085d875e2441333af..1cfafe5452b1b847e2ee5baea9d10a93bea49143 100644
--- a/src/backend/optimizer/prep/prepqual.c
+++ b/src/backend/optimizer/prep/prepqual.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.41 2003/12/30 21:49:19 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.42 2004/05/26 04:41:26 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -144,7 +144,7 @@ flatten_andors_mutator(Node *node, void *context)
 static void
 flatten_andors_and_walker(FastList *out_list, List *andlist)
 {
-	List	   *arg;
+	ListCell   *arg;
 
 	foreach(arg, andlist)
 	{
@@ -160,7 +160,7 @@ flatten_andors_and_walker(FastList *out_list, List *andlist)
 static void
 flatten_andors_or_walker(FastList *out_list, List *orlist)
 {
-	List	   *arg;
+	ListCell   *arg;
 
 	foreach(arg, orlist)
 	{
@@ -193,7 +193,7 @@ pull_ands(List *andlist)
 static void
 pull_ands_walker(FastList *out_list, List *andlist)
 {
-	List	   *arg;
+	ListCell   *arg;
 
 	foreach(arg, andlist)
 	{
@@ -226,7 +226,7 @@ pull_ors(List *orlist)
 static void
 pull_ors_walker(FastList *out_list, List *orlist)
 {
-	List	   *arg;
+	ListCell   *arg;
 
 	foreach(arg, orlist)
 	{
@@ -258,7 +258,7 @@ find_nots(Expr *qual)
 	if (and_clause((Node *) qual))
 	{
 		FastList	t_list;
-		List	   *temp;
+		ListCell   *temp;
 
 		FastListInit(&t_list);
 		foreach(temp, ((BoolExpr *) qual)->args)
@@ -268,7 +268,7 @@ find_nots(Expr *qual)
 	else if (or_clause((Node *) qual))
 	{
 		FastList	t_list;
-		List	   *temp;
+		ListCell   *temp;
 
 		FastListInit(&t_list);
 		foreach(temp, ((BoolExpr *) qual)->args)
@@ -324,7 +324,7 @@ push_nots(Expr *qual)
 		 *--------------------
 		 */
 		FastList	t_list;
-		List	   *temp;
+		ListCell   *temp;
 
 		FastListInit(&t_list);
 		foreach(temp, ((BoolExpr *) qual)->args)
@@ -334,7 +334,7 @@ push_nots(Expr *qual)
 	else if (or_clause((Node *) qual))
 	{
 		FastList	t_list;
-		List	   *temp;
+		ListCell   *temp;
 
 		FastListInit(&t_list);
 		foreach(temp, ((BoolExpr *) qual)->args)
@@ -398,7 +398,7 @@ find_duplicate_ors(Expr *qual)
 	if (or_clause((Node *) qual))
 	{
 		List	   *orlist = NIL;
-		List	   *temp;
+		ListCell   *temp;
 
 		/* Recurse */
 		foreach(temp, ((BoolExpr *) qual)->args)
@@ -412,7 +412,7 @@ find_duplicate_ors(Expr *qual)
 	else if (and_clause((Node *) qual))
 	{
 		List	   *andlist = NIL;
-		List	   *temp;
+		ListCell   *temp;
 
 		/* Recurse */
 		foreach(temp, ((BoolExpr *) qual)->args)
@@ -441,13 +441,12 @@ process_duplicate_ors(List *orlist)
 	int			num_subclauses = 0;
 	List	   *winners;
 	List	   *neworlist;
-	List	   *temp;
-	List	   *temp2;
+	ListCell   *temp;
 
 	if (orlist == NIL)
 		return NULL;			/* probably can't happen */
-	if (lnext(orlist) == NIL)
-		return lfirst(orlist);	/* single-expression OR (can this happen?) */
+	if (length(orlist) == 1)	/* single-expression OR (can this happen?) */
+		return linitial(orlist);
 
 	/*
 	 * Choose the shortest AND clause as the reference list --- obviously,
@@ -457,7 +456,7 @@ process_duplicate_ors(List *orlist)
 	 */
 	foreach(temp, orlist)
 	{
-		Expr	   *clause = lfirst(temp);
+		Expr	   *clause = (Expr *) lfirst(temp);
 
 		if (and_clause((Node *) clause))
 		{
@@ -489,12 +488,13 @@ process_duplicate_ors(List *orlist)
 	winners = NIL;
 	foreach(temp, reference)
 	{
-		Expr	   *refclause = lfirst(temp);
+		Expr	   *refclause = (Expr *) lfirst(temp);
 		bool		win = true;
+		ListCell   *temp2;
 
 		foreach(temp2, orlist)
 		{
-			Expr	   *clause = lfirst(temp2);
+			Expr	   *clause = (Expr *) lfirst(temp2);
 
 			if (and_clause((Node *) clause))
 			{
@@ -537,7 +537,7 @@ process_duplicate_ors(List *orlist)
 	neworlist = NIL;
 	foreach(temp, orlist)
 	{
-		Expr	   *clause = lfirst(temp);
+		Expr	   *clause = (Expr *) lfirst(temp);
 
 		if (and_clause((Node *) clause))
 		{
@@ -546,8 +546,8 @@ process_duplicate_ors(List *orlist)
 			subclauses = set_difference(subclauses, winners);
 			if (subclauses != NIL)
 			{
-				if (lnext(subclauses) == NIL)
-					neworlist = lappend(neworlist, lfirst(subclauses));
+				if (length(subclauses) == 1)
+					neworlist = lappend(neworlist, linitial(subclauses));
 				else
 					neworlist = lappend(neworlist, make_andclause(subclauses));
 			}
@@ -577,8 +577,8 @@ process_duplicate_ors(List *orlist)
 	 */
 	if (neworlist != NIL)
 	{
-		if (lnext(neworlist) == NIL)
-			winners = lappend(winners, lfirst(neworlist));
+		if (length(neworlist) == 1)
+			winners = lappend(winners, linitial(neworlist));
 		else
 			winners = lappend(winners, make_orclause(pull_ors(neworlist)));
 	}
@@ -587,8 +587,8 @@ process_duplicate_ors(List *orlist)
 	 * And return the constructed AND clause, again being wary of a single
 	 * element and AND/OR flatness.
 	 */
-	if (lnext(winners) == NIL)
-		return (Expr *) lfirst(winners);
+	if (length(winners) == 1)
+		return (Expr *) linitial(winners);
 	else
 		return make_andclause(pull_ands(winners));
 }
diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index 86a14cacd8080344b9082d6da38989ceb69cbf39..89df7bca35a2fc9be493359752a07f4dc3cbd58b 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.66 2003/11/29 19:51:51 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.67 2004/05/26 04:41:26 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -122,10 +122,13 @@ expand_targetlist(List *tlist, int command_type,
 				  Index result_relation, List *range_table)
 {
 	List	   *new_tlist = NIL;
+	ListCell   *tlist_item;
 	Relation	rel;
 	int			attrno,
 				numattrs;
 
+	tlist_item = list_head(tlist);
+
 	/*
 	 * The rewriter should have already ensured that the TLEs are in
 	 * correct order; but we have to insert TLEs for any missing
@@ -143,15 +146,15 @@ expand_targetlist(List *tlist, int command_type,
 		Form_pg_attribute att_tup = rel->rd_att->attrs[attrno - 1];
 		TargetEntry *new_tle = NULL;
 
-		if (tlist != NIL)
+		if (tlist_item != NULL)
 		{
-			TargetEntry *old_tle = (TargetEntry *) lfirst(tlist);
+			TargetEntry *old_tle = (TargetEntry *) lfirst(tlist_item);
 			Resdom	   *resdom = old_tle->resdom;
 
 			if (!resdom->resjunk && resdom->resno == attrno)
 			{
 				new_tle = old_tle;
-				tlist = lnext(tlist);
+				tlist_item = lnext(tlist_item);
 			}
 		}
 
@@ -259,9 +262,9 @@ expand_targetlist(List *tlist, int command_type,
 	 * an UPDATE in a table with dropped columns, or an inheritance child
 	 * table with extra columns.)
 	 */
-	while (tlist)
+	while (tlist_item)
 	{
-		TargetEntry *old_tle = (TargetEntry *) lfirst(tlist);
+		TargetEntry *old_tle = (TargetEntry *) lfirst(tlist_item);
 		Resdom	   *resdom = old_tle->resdom;
 
 		if (!resdom->resjunk)
@@ -275,7 +278,7 @@ expand_targetlist(List *tlist, int command_type,
 		}
 		new_tlist = lappend(new_tlist, old_tle);
 		attrno++;
-		tlist = lnext(tlist);
+		tlist_item = lnext(tlist_item);
 	}
 
 	heap_close(rel, AccessShareLock);
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 25dfc2611e8ab9466ba31a2b750fd2d3c4f7d3b2..41809bd69e0636d766f57a6b5998a4543b149f48 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -14,7 +14,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.110 2004/05/11 22:43:55 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.111 2004/05/26 04:41:26 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -420,15 +420,19 @@ generate_setop_tlist(List *colTypes, int flag,
 {
 	List	   *tlist = NIL;
 	int			resno = 1;
-	List	   *i;
+	ListCell   *i,
+			   *j,
+			   *k;
 	Resdom	   *resdom;
 	Node	   *expr;
 
+	j = list_head(input_tlist);
+	k = list_head(refnames_tlist);
 	foreach(i, colTypes)
 	{
 		Oid			colType = lfirsto(i);
-		TargetEntry *inputtle = (TargetEntry *) lfirst(input_tlist);
-		TargetEntry *reftle = (TargetEntry *) lfirst(refnames_tlist);
+		TargetEntry *inputtle = (TargetEntry *) lfirst(j);
+		TargetEntry *reftle = (TargetEntry *) lfirst(k);
 		int32		colTypmod;
 
 		Assert(inputtle->resdom->resno == resno);
@@ -476,8 +480,8 @@ generate_setop_tlist(List *colTypes, int flag,
 							pstrdup(reftle->resdom->resname),
 							false);
 		tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
-		input_tlist = lnext(input_tlist);
-		refnames_tlist = lnext(refnames_tlist);
+		j = lnext(j);
+		k = lnext(k);
 	}
 
 	if (flag >= 0)
@@ -518,11 +522,12 @@ generate_append_tlist(List *colTypes, bool flag,
 {
 	List	   *tlist = NIL;
 	int			resno = 1;
-	List	   *curColType;
+	ListCell   *curColType;
+	ListCell   *ref_tl_item;
 	int			colindex;
 	Resdom	   *resdom;
 	Node	   *expr;
-	List	   *planl;
+	ListCell   *planl;
 	int32	   *colTypmods;
 
 	/*
@@ -536,9 +541,9 @@ generate_append_tlist(List *colTypes, bool flag,
 	foreach(planl, input_plans)
 	{
 		Plan	   *subplan = (Plan *) lfirst(planl);
-		List	   *subtlist;
+		ListCell   *subtlist;
 
-		curColType = colTypes;
+		curColType = list_head(colTypes);
 		colindex = 0;
 		foreach(subtlist, subplan->targetlist)
 		{
@@ -546,11 +551,11 @@ generate_append_tlist(List *colTypes, bool flag,
 
 			if (subtle->resdom->resjunk)
 				continue;
-			Assert(curColType != NIL);
-			if (subtle->resdom->restype == lfirsto(curColType))
+			Assert(curColType != NULL);
+			if (subtle->resdom->restype == lfirst_oid(curColType))
 			{
 				/* If first subplan, copy the typmod; else compare */
-				if (planl == input_plans)
+				if (planl == list_head(input_plans))
 					colTypmods[colindex] = subtle->resdom->restypmod;
 				else if (subtle->resdom->restypmod != colTypmods[colindex])
 					colTypmods[colindex] = -1;
@@ -563,18 +568,18 @@ generate_append_tlist(List *colTypes, bool flag,
 			curColType = lnext(curColType);
 			colindex++;
 		}
-		Assert(curColType == NIL);
+		Assert(curColType == NULL);
 	}
 
 	/*
 	 * Now we can build the tlist for the Append.
 	 */
 	colindex = 0;
-	foreach(curColType, colTypes)
+	forboth(curColType, colTypes, ref_tl_item, refnames_tlist)
 	{
 		Oid			colType = lfirsto(curColType);
 		int32		colTypmod = colTypmods[colindex++];
-		TargetEntry *reftle = (TargetEntry *) lfirst(refnames_tlist);
+		TargetEntry *reftle = (TargetEntry *) lfirst(ref_tl_item);
 
 		Assert(reftle->resdom->resno == resno);
 		Assert(!reftle->resdom->resjunk);
@@ -589,7 +594,6 @@ generate_append_tlist(List *colTypes, bool flag,
 							pstrdup(reftle->resdom->resname),
 							false);
 		tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
-		refnames_tlist = lnext(refnames_tlist);
 	}
 
 	if (flag)
@@ -623,11 +627,12 @@ generate_append_tlist(List *colTypes, bool flag,
 static bool
 tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
 {
-	List	   *i;
+	ListCell   *l;
+	ListCell   *curColType = list_head(colTypes);
 
-	foreach(i, tlist)
+	foreach(l, tlist)
 	{
-		TargetEntry *tle = (TargetEntry *) lfirst(i);
+		TargetEntry *tle = (TargetEntry *) lfirst(l);
 
 		if (tle->resdom->resjunk)
 		{
@@ -636,14 +641,14 @@ tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
 		}
 		else
 		{
-			if (colTypes == NIL)
+			if (curColType == NULL)
 				return false;
-			if (tle->resdom->restype != lfirsto(colTypes))
+			if (tle->resdom->restype != lfirst_oid(curColType))
 				return false;
-			colTypes = lnext(colTypes);
+			curColType = lnext(curColType);
 		}
 	}
-	if (colTypes != NIL)
+	if (curColType != NULL)
 		return false;
 	return true;
 }
@@ -667,10 +672,10 @@ find_all_inheritors(Oid parentrel)
 	 */
 	while (unexamined_relids != NIL)
 	{
-		Oid			currentrel = lfirsto(unexamined_relids);
+		Oid			currentrel = linitial_oid(unexamined_relids);
 		List	   *currentchildren;
 
-		unexamined_relids = lnext(unexamined_relids);
+		unexamined_relids = list_delete_first(unexamined_relids);
 		examined_relids = lappendo(examined_relids, currentrel);
 		currentchildren = find_inheritance_children(currentrel);
 
@@ -719,7 +724,7 @@ expand_inherited_rtentry(Query *parse, Index rti, bool dup_parent)
 	Oid			parentOID;
 	List	   *inhOIDs;
 	List	   *inhRTIs;
-	List	   *l;
+	ListCell   *l;
 
 	/* Does RT entry allow inheritance? */
 	if (!rte->inh)
@@ -739,7 +744,7 @@ expand_inherited_rtentry(Query *parse, Index rti, bool dup_parent)
 	 * case.  This could happen despite above has_subclass() check, if
 	 * table once had a child but no longer does.
 	 */
-	if (lnext(inhOIDs) == NIL)
+	if (length(inhOIDs) < 2)
 		return NIL;
 	/* OK, it's an inheritance set; expand it */
 	if (dup_parent)
@@ -1020,7 +1025,7 @@ static List *
 adjust_inherited_tlist(List *tlist, Oid old_relid, Oid new_relid)
 {
 	bool		changed_it = false;
-	List	   *tl;
+	ListCell   *tl;
 	List	   *new_tlist;
 	bool		more;
 	int			attrno;
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 4dabbf50dac8a2b2a7d1d9e7c28776412381a074..0727bfb6f2c0f10fbe0007bdc4f9298a69ebe0eb 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.170 2004/05/10 22:44:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.171 2004/05/26 04:41:27 neilc Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -114,7 +114,7 @@ get_leftop(Expr *clause)
 	OpExpr	   *expr = (OpExpr *) clause;
 
 	if (expr->args != NIL)
-		return lfirst(expr->args);
+		return linitial(expr->args);
 	else
 		return NULL;
 }
@@ -130,8 +130,8 @@ get_rightop(Expr *clause)
 {
 	OpExpr	   *expr = (OpExpr *) clause;
 
-	if (expr->args != NIL && lnext(expr->args) != NIL)
-		return lfirst(lnext(expr->args));
+	if (list_length(expr->args) >= 2)
+		return lsecond(expr->args);
 	else
 		return NULL;
 }
@@ -176,7 +176,7 @@ make_notclause(Expr *notclause)
 Expr *
 get_notclausearg(Expr *notclause)
 {
-	return lfirst(((BoolExpr *) notclause)->args);
+	return linitial(((BoolExpr *) notclause)->args);
 }
 
 /*****************************************************************************
@@ -278,8 +278,8 @@ make_ands_explicit(List *andclauses)
 {
 	if (andclauses == NIL)
 		return (Expr *) makeBoolConst(true, false);
-	else if (lnext(andclauses) == NIL)
-		return (Expr *) lfirst(andclauses);
+	else if (length(andclauses) == 1)
+		return (Expr *) linitial(andclauses);
 	else
 		return make_andclause(andclauses);
 }
@@ -595,7 +595,7 @@ contain_mutable_functions_walker(Node *node, void *context)
 	if (IsA(node, SubLink))
 	{
 		SubLink    *sublink = (SubLink *) node;
-		List	   *opid;
+		ListCell   *opid;
 
 		foreach(opid, sublink->operOids)
 		{
@@ -678,7 +678,7 @@ contain_volatile_functions_walker(Node *node, void *context)
 	if (IsA(node, SubLink))
 	{
 		SubLink    *sublink = (SubLink *) node;
-		List	   *opid;
+		ListCell   *opid;
 
 		foreach(opid, sublink->operOids)
 		{
@@ -848,7 +848,7 @@ pull_constant_clauses(List *quals, List **constantQual)
 {
 	FastList	constqual,
 				restqual;
-	List	   *q;
+	ListCell   *q;
 
 	FastListInit(&constqual);
 	FastListInit(&restqual);
@@ -882,7 +882,7 @@ pull_constant_clauses(List *quals, List **constantQual)
 bool
 has_distinct_on_clause(Query *query)
 {
-	List	   *targetList;
+	ListCell   *l;
 
 	/* Is there a DISTINCT clause at all? */
 	if (query->distinctClause == NIL)
@@ -901,9 +901,9 @@ has_distinct_on_clause(Query *query)
 	 * This code assumes that the DISTINCT list is valid, ie, all its entries
 	 * match some entry of the tlist.
 	 */
-	foreach(targetList, query->targetList)
+	foreach(l, query->targetList)
 	{
-		TargetEntry *tle = (TargetEntry *) lfirst(targetList);
+		TargetEntry *tle = (TargetEntry *) lfirst(l);
 
 		if (tle->resdom->ressortgroupref == 0)
 		{
@@ -998,8 +998,8 @@ CommuteClause(OpExpr *clause)
 	clause->opfuncid = InvalidOid;
 	/* opresulttype and opretset are assumed not to change */
 
-	temp = lfirst(clause->args);
-	lfirst(clause->args) = lsecond(clause->args);
+	temp = linitial(clause->args);
+	linitial(clause->args) = lsecond(clause->args);
 	lsecond(clause->args) = temp;
 }
 
@@ -1162,7 +1162,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 	{
 		DistinctExpr *expr = (DistinctExpr *) node;
 		List	   *args;
-		List	   *arg;
+		ListCell   *arg;
 		bool		has_null_input = false;
 		bool		all_null_input = true;
 		bool		has_nonconst_input = false;
@@ -1281,8 +1281,8 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 					if (newargs == NIL)
 						return makeBoolConst(false, false);
 					/* If only one nonconst-or-NULL input, it's the result */
-					if (lnext(newargs) == NIL)
-						return (Node *) lfirst(newargs);
+					if (length(newargs) == 1)
+						return (Node *) linitial(newargs);
 					/* Else we still need an OR node */
 					return (Node *) make_orclause(newargs);
 				}
@@ -1302,16 +1302,16 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 					if (newargs == NIL)
 						return makeBoolConst(true, false);
 					/* If only one nonconst-or-NULL input, it's the result */
-					if (lnext(newargs) == NIL)
-						return (Node *) lfirst(newargs);
+					if (length(newargs) == 1)
+						return (Node *) linitial(newargs);
 					/* Else we still need an AND node */
 					return (Node *) make_andclause(newargs);
 				}
 			case NOT_EXPR:
 				Assert(length(args) == 1);
-				if (IsA(lfirst(args), Const))
+				if (IsA(linitial(args), Const))
 				{
-					Const *const_input = (Const *) lfirst(args);
+					Const *const_input = (Const *) linitial(args);
 
 					/* NOT NULL => NULL */
 					if (const_input->constisnull)
@@ -1320,13 +1320,13 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 					return makeBoolConst(!DatumGetBool(const_input->constvalue),
 										 false);
 				}
-				else if (not_clause((Node *) lfirst(args)))
+				else if (not_clause((Node *) linitial(args)))
 				{
 					/* Cancel NOT/NOT */
-					return (Node *) get_notclausearg((Expr *) lfirst(args));
+					return (Node *) get_notclausearg((Expr *) linitial(args));
 				}
 				/* Else we still need a NOT node */
-				return (Node *) make_notclause((Expr *) lfirst(args));
+				return (Node *) make_notclause((Expr *) linitial(args));
 			default:
 				elog(ERROR, "unrecognized boolop: %d",
 					 (int) expr->boolop);
@@ -1414,7 +1414,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 		FastList	newargs;
 		Node	   *defresult;
 		Const	   *const_input;
-		List	   *arg;
+		ListCell   *arg;
 
 		/* Simplify the test expression, if any */
 		newarg = eval_const_expressions_mutator((Node *) caseexpr->arg,
@@ -1480,7 +1480,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 		ArrayExpr  *newarray;
 		bool		all_const = true;
 		FastList	newelems;
-		List	   *element;
+		ListCell   *element;
 
 		FastListInit(&newelems);
 		foreach(element, arrayexpr->elements)
@@ -1511,7 +1511,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 		CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
 		CoalesceExpr *newcoalesce;
 		FastList	newargs;
-		List	   *arg;
+		ListCell   *arg;
 
 		FastListInit(&newargs);
 		foreach(arg, coalesceexpr->args)
@@ -1614,7 +1614,7 @@ static List *
 simplify_or_arguments(List *args, bool *haveNull, bool *forceTrue)
 {
 	List	   *newargs = NIL;
-	List	   *larg;
+	ListCell   *larg;
 
 	foreach(larg, args)
 	{
@@ -1675,7 +1675,7 @@ static List *
 simplify_and_arguments(List *args, bool *haveNull, bool *forceFalse)
 {
 	List	   *newargs = NIL;
-	List	   *larg;
+	ListCell   *larg;
 
 	foreach(larg, args)
 	{
@@ -1774,7 +1774,7 @@ evaluate_function(Oid funcid, Oid result_type, List *args,
 	Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
 	bool		has_nonconst_input = false;
 	bool		has_null_input = false;
-	List	   *arg;
+	ListCell   *arg;
 	FuncExpr   *newexpr;
 
 	/*
@@ -1870,7 +1870,7 @@ inline_function(Oid funcid, Oid result_type, List *args,
 	Query	   *querytree;
 	Node	   *newexpr;
 	int		   *usecounts;
-	List	   *arg;
+	ListCell   *arg;
 	int			i;
 
 	/*
@@ -1946,13 +1946,13 @@ inline_function(Oid funcid, Oid result_type, List *args,
 	if (length(raw_parsetree_list) != 1)
 		goto fail;
 
-	querytree_list = parse_analyze(lfirst(raw_parsetree_list),
+	querytree_list = parse_analyze(linitial(raw_parsetree_list),
 								   argtypes, funcform->pronargs);
 
 	if (length(querytree_list) != 1)
 		goto fail;
 
-	querytree = (Query *) lfirst(querytree_list);
+	querytree = (Query *) linitial(querytree_list);
 
 	/*
 	 * The single command must be a simple "SELECT expression".
@@ -1976,7 +1976,7 @@ inline_function(Oid funcid, Oid result_type, List *args,
 		length(querytree->targetList) != 1)
 		goto fail;
 
-	newexpr = (Node *) ((TargetEntry *) lfirst(querytree->targetList))->expr;
+	newexpr = (Node *) ((TargetEntry *) linitial(querytree->targetList))->expr;
 
 	/*
 	 * If the function has any arguments declared as polymorphic types,
@@ -2330,7 +2330,7 @@ expression_tree_walker(Node *node,
 					   bool (*walker) (),
 					   void *context)
 {
-	List	   *temp;
+	ListCell   *temp;
 
 	/*
 	 * The walker has already visited the current node, and so we need
@@ -2576,7 +2576,7 @@ query_tree_walker(Query *query,
 				  void *context,
 				  int flags)
 {
-	List	   *rt;
+	ListCell   *rt;
 
 	Assert(query != NULL && IsA(query, Query));
 
@@ -2972,7 +2972,7 @@ expression_tree_mutator(Node *node,
 				 * elements!
 				 */
 				FastList	resultlist;
-				List	   *temp;
+				ListCell   *temp;
 
 				FastListInit(&resultlist);
 				foreach(temp, (List *) node)
@@ -3064,7 +3064,7 @@ query_tree_mutator(Query *query,
 				   int flags)
 {
 	FastList	newrt;
-	List	   *rt;
+	ListCell   *rt;
 
 	Assert(query != NULL && IsA(query, Query));
 
diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c
index 9c207ac96efd69596d40f012073f026b5fedbcd5..7c082754c305ae49885308435e2a7dfcdbd5fc7d 100644
--- a/src/backend/optimizer/util/joininfo.c
+++ b/src/backend/optimizer/util/joininfo.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/util/joininfo.c,v 1.37 2003/11/29 19:51:51 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/joininfo.c,v 1.38 2004/05/26 04:41:27 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,11 +29,11 @@
 JoinInfo *
 find_joininfo_node(RelOptInfo *this_rel, Relids join_relids)
 {
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, this_rel->joininfo)
+	foreach(l, this_rel->joininfo)
 	{
-		JoinInfo   *joininfo = (JoinInfo *) lfirst(i);
+		JoinInfo   *joininfo = (JoinInfo *) lfirst(l);
 
 		if (bms_equal(join_relids, joininfo->unjoined_relids))
 			return joininfo;
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 619013a18d584a73e62782e08afe6b41c9258d75..3bad7a4f6010a72484924d3d86cb208585d28192 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.104 2004/04/25 18:23:56 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.105 2004/05/26 04:41:27 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -200,7 +200,7 @@ void
 set_cheapest(RelOptInfo *parent_rel)
 {
 	List	   *pathlist = parent_rel->pathlist;
-	List	   *p;
+	ListCell   *p;
 	Path	   *cheapest_startup_path;
 	Path	   *cheapest_total_path;
 
@@ -209,9 +209,9 @@ set_cheapest(RelOptInfo *parent_rel)
 	if (pathlist == NIL)
 		elog(ERROR, "could not devise a query plan for the given query");
 
-	cheapest_startup_path = cheapest_total_path = (Path *) lfirst(pathlist);
+	cheapest_startup_path = cheapest_total_path = (Path *) linitial(pathlist);
 
-	foreach(p, lnext(pathlist))
+	for_each_cell(p, lnext(list_head(pathlist)))
 	{
 		Path	   *path = (Path *) lfirst(p);
 		int			cmp;
@@ -269,17 +269,17 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
 {
 	bool		accept_new = true;		/* unless we find a superior old
 										 * path */
-	List	   *insert_after = NIL;		/* where to insert new item */
-	List	   *p1_prev = NIL;
-	List	   *p1;
+	ListCell   *insert_after = NULL;	/* where to insert new item */
+	ListCell   *p1_prev = NULL;
+	ListCell   *p1;
 
 	/*
 	 * Loop to check proposed new path against old paths.  Note it is
 	 * possible for more than one old path to be tossed out because
 	 * new_path dominates it.
 	 */
-	p1 = parent_rel->pathlist;	/* cannot use foreach here */
-	while (p1 != NIL)
+	p1 = list_head(parent_rel->pathlist);	/* cannot use foreach here */
+	while (p1 != NULL)
 	{
 		Path	   *old_path = (Path *) lfirst(p1);
 		bool		remove_old = false; /* unless new proves superior */
@@ -346,15 +346,14 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
 		 */
 		if (remove_old)
 		{
-			List	   *p1_next = lnext(p1);
-
+			parent_rel->pathlist = list_delete_cell(parent_rel->pathlist,
+													p1, p1_prev);
+			/* Delete the data pointed-to by the deleted cell */
+			pfree(old_path);
 			if (p1_prev)
-				lnext(p1_prev) = p1_next;
+				p1 = lnext(p1_prev);
 			else
-				parent_rel->pathlist = p1_next;
-			pfree(old_path);
-			pfree(p1);			/* this is why we can't use foreach */
-			p1 = p1_next;
+				p1 = list_head(parent_rel->pathlist);
 		}
 		else
 		{
@@ -378,7 +377,7 @@ add_path(RelOptInfo *parent_rel, Path *new_path)
 	{
 		/* Accept the new path: insert it at proper place in pathlist */
 		if (insert_after)
-			lnext(insert_after) = lcons(new_path, lnext(insert_after));
+			lappend_cell(parent_rel->pathlist, insert_after, new_path);
 		else
 			parent_rel->pathlist = lcons(new_path, parent_rel->pathlist);
 	}
@@ -508,7 +507,7 @@ AppendPath *
 create_append_path(RelOptInfo *rel, List *subpaths)
 {
 	AppendPath *pathnode = makeNode(AppendPath);
-	List	   *l;
+	ListCell   *l;
 
 	pathnode->path.pathtype = T_Append;
 	pathnode->path.parent = rel;
@@ -522,7 +521,7 @@ create_append_path(RelOptInfo *rel, List *subpaths)
 	{
 		Path	   *subpath = (Path *) lfirst(l);
 
-		if (l == subpaths)		/* first node? */
+		if (l == list_head(subpaths))		/* first node? */
 			pathnode->path.startup_cost = subpath->startup_cost;
 		pathnode->path.total_cost += subpath->total_cost;
 	}
@@ -608,7 +607,7 @@ create_unique_path(Query *root, RelOptInfo *rel, Path *subpath)
 	Path		agg_path;		/* dummy for result of cost_agg */
 	MemoryContext oldcontext;
 	List	   *sub_targetlist;
-	List	   *l;
+	ListCell   *l;
 	int			numCols;
 
 	/* Caller made a mistake if subpath isn't cheapest_total */
@@ -783,7 +782,7 @@ is_distinct_query(Query *query)
 	 */
 	if (query->groupClause)
 	{
-		List   *gl;
+		ListCell   *gl;
 
 		foreach(gl, query->groupClause)
 		{
@@ -818,7 +817,7 @@ is_distinct_query(Query *query)
 static bool
 hash_safe_tlist(List *tlist)
 {
-	List	   *tl;
+	ListCell   *tl;
 
 	foreach(tl, tlist)
 	{
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 37067dd4d42528408eba94e62a44391bb5b774b6..55b9a12d8cf7005e875cd5551b8d0d9af0cdca72 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.91 2004/01/04 00:07:32 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.92 2004/05/26 04:41:27 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -75,14 +75,14 @@ get_relation_info(Oid relationObjectId, RelOptInfo *rel)
 
 	if (hasindex)
 	{
-		List	   *indexoidlist,
-				   *indexoidscan;
+		List	   *indexoidlist;
+		ListCell   *l;
 
 		indexoidlist = RelationGetIndexList(relation);
 
-		foreach(indexoidscan, indexoidlist)
+		foreach(l, indexoidlist)
 		{
-			Oid			indexoid = lfirsto(indexoidscan);
+			Oid			indexoid = lfirsto(l);
 			Relation	indexRelation;
 			Form_pg_index index;
 			IndexOptInfo *info;
@@ -384,7 +384,7 @@ has_subclass(Oid relationId)
 bool
 has_unique_index(RelOptInfo *rel, AttrNumber attno)
 {
-	List	   *ilist;
+	ListCell   *ilist;
 
 	foreach(ilist, rel->indexlist)
 	{
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index d6853ca819d08ea35f4bb58dd23e8214d422711e..8969b2d61850f7906d08e9b044927dbb9ef3bcf2 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/util/relnode.c,v 1.56 2004/04/25 18:23:56 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/relnode.c,v 1.57 2004/05/26 04:41:27 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,21 +47,21 @@ static void subbuild_joinrel_joinlist(RelOptInfo *joinrel,
 void
 build_base_rel(Query *root, int relid)
 {
-	List	   *rels;
+	ListCell   *l;
 	RelOptInfo *rel;
 
 	/* Rel should not exist already */
-	foreach(rels, root->base_rel_list)
+	foreach(l, root->base_rel_list)
 	{
-		rel = (RelOptInfo *) lfirst(rels);
+		rel = (RelOptInfo *) lfirst(l);
 		if (relid == rel->relid)
 			elog(ERROR, "rel already exists");
 	}
 
 	/* It should not exist as an "other" rel, either */
-	foreach(rels, root->other_rel_list)
+	foreach(l, root->other_rel_list)
 	{
-		rel = (RelOptInfo *) lfirst(rels);
+		rel = (RelOptInfo *) lfirst(l);
 		if (relid == rel->relid)
 			elog(ERROR, "rel already exists as \"other\" rel");
 	}
@@ -82,21 +82,21 @@ build_base_rel(Query *root, int relid)
 RelOptInfo *
 build_other_rel(Query *root, int relid)
 {
-	List	   *rels;
+	ListCell   *l;
 	RelOptInfo *rel;
 
 	/* Already made? */
-	foreach(rels, root->other_rel_list)
+	foreach(l, root->other_rel_list)
 	{
-		rel = (RelOptInfo *) lfirst(rels);
+		rel = (RelOptInfo *) lfirst(l);
 		if (relid == rel->relid)
 			return rel;
 	}
 
 	/* It should not exist as a base rel */
-	foreach(rels, root->base_rel_list)
+	foreach(l, root->base_rel_list)
 	{
-		rel = (RelOptInfo *) lfirst(rels);
+		rel = (RelOptInfo *) lfirst(l);
 		if (relid == rel->relid)
 			elog(ERROR, "rel already exists as base rel");
 	}
@@ -187,19 +187,19 @@ make_base_rel(Query *root, int relid)
 RelOptInfo *
 find_base_rel(Query *root, int relid)
 {
-	List	   *rels;
+	ListCell   *l;
 	RelOptInfo *rel;
 
-	foreach(rels, root->base_rel_list)
+	foreach(l, root->base_rel_list)
 	{
-		rel = (RelOptInfo *) lfirst(rels);
+		rel = (RelOptInfo *) lfirst(l);
 		if (relid == rel->relid)
 			return rel;
 	}
 
-	foreach(rels, root->other_rel_list)
+	foreach(l, root->other_rel_list)
 	{
-		rel = (RelOptInfo *) lfirst(rels);
+		rel = (RelOptInfo *) lfirst(l);
 		if (relid == rel->relid)
 			return rel;
 	}
@@ -217,11 +217,11 @@ find_base_rel(Query *root, int relid)
 RelOptInfo *
 find_join_rel(Query *root, Relids relids)
 {
-	List	   *joinrels;
+	ListCell   *l;
 
-	foreach(joinrels, root->join_rel_list)
+	foreach(l, root->join_rel_list)
 	{
-		RelOptInfo *rel = (RelOptInfo *) lfirst(joinrels);
+		RelOptInfo *rel = (RelOptInfo *) lfirst(l);
 
 		if (bms_equal(rel->relids, relids))
 			return rel;
@@ -363,8 +363,7 @@ static void
 build_joinrel_tlist(Query *root, RelOptInfo *joinrel)
 {
 	Relids		relids = joinrel->relids;
-	List	   *rels;
-	List	   *vars;
+	ListCell   *rels;
 
 	FastListInit(&joinrel->reltargetlist);
 	joinrel->width = 0;
@@ -372,6 +371,7 @@ build_joinrel_tlist(Query *root, RelOptInfo *joinrel)
 	foreach(rels, root->base_rel_list)
 	{
 		RelOptInfo *baserel = (RelOptInfo *) lfirst(rels);
+		ListCell   *vars;
 
 		if (!bms_is_member(baserel->relid, relids))
 			continue;
@@ -481,7 +481,7 @@ subbuild_joinrel_restrictlist(RelOptInfo *joinrel,
 							  List *joininfo_list)
 {
 	List	   *restrictlist = NIL;
-	List	   *xjoininfo;
+	ListCell   *xjoininfo;
 
 	foreach(xjoininfo, joininfo_list)
 	{
@@ -515,7 +515,7 @@ static void
 subbuild_joinrel_joinlist(RelOptInfo *joinrel,
 						  List *joininfo_list)
 {
-	List	   *xjoininfo;
+	ListCell   *xjoininfo;
 
 	foreach(xjoininfo, joininfo_list)
 	{
diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c
index ddf965fdf2bde3569932dbf91b88dc8ef3e5bdf7..1cb446e44fa8ab7bdfcb001ae1b774760872b927 100644
--- a/src/backend/optimizer/util/restrictinfo.c
+++ b/src/backend/optimizer/util/restrictinfo.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.26 2004/02/27 21:48:04 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.27 2004/05/26 04:41:27 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -93,14 +93,14 @@ make_restrictinfo_from_indexclauses(List *indexclauses,
 {
 	List	   *withris = NIL;
 	List	   *withoutris = NIL;
-	List	   *orlist;
+	ListCell   *orlist;
 
 	/* Empty list probably can't happen, but here's what to do */
 	if (indexclauses == NIL)
 		return NIL;
 	/* If single indexscan, just return the ANDed clauses */
-	if (lnext(indexclauses) == NIL)
-		return (List *) lfirst(indexclauses);
+	if (length(indexclauses) == 1)
+		return (List *) linitial(indexclauses);
 	/* Else we need an OR RestrictInfo structure */
 	foreach(orlist, indexclauses)
 	{
@@ -206,7 +206,7 @@ make_sub_restrictinfos(Expr *clause, bool is_pushed_down,
 	if (or_clause((Node *) clause))
 	{
 		List	   *orlist = NIL;
-		List	   *temp;
+		ListCell   *temp;
 
 		foreach(temp, ((BoolExpr *) clause)->args)
 			orlist = lappend(orlist,
@@ -218,7 +218,7 @@ make_sub_restrictinfos(Expr *clause, bool is_pushed_down,
 	else if (and_clause((Node *) clause))
 	{
 		List	   *andlist = NIL;
-		List	   *temp;
+		ListCell   *temp;
 
 		foreach(temp, ((BoolExpr *) clause)->args)
 			andlist = lappend(andlist,
@@ -257,7 +257,7 @@ List *
 get_actual_clauses(List *restrictinfo_list)
 {
 	List	   *result = NIL;
-	List	   *temp;
+	ListCell   *temp;
 
 	foreach(temp, restrictinfo_list)
 	{
@@ -280,7 +280,7 @@ void
 get_actual_join_clauses(List *restrictinfo_list,
 						List **joinquals, List **otherquals)
 {
-	List	   *temp;
+	ListCell   *temp;
 
 	*joinquals = NIL;
 	*otherquals = NIL;
@@ -317,7 +317,7 @@ remove_redundant_join_clauses(Query *root, List *restrictinfo_list,
 							  JoinType jointype)
 {
 	List	   *result = NIL;
-	List	   *item;
+	ListCell   *item;
 	QualCost	cost;
 
 	/*
@@ -380,7 +380,7 @@ select_nonredundant_join_clauses(Query *root,
 								 JoinType jointype)
 {
 	List	   *result = NIL;
-	List	   *item;
+	ListCell   *item;
 
 	foreach(item, restrictinfo_list)
 	{
@@ -431,7 +431,7 @@ join_clause_is_redundant(Query *root,
 						 List *reference_list,
 						 JoinType jointype)
 {
-	List	   *refitem;
+	ListCell   *refitem;
 
 	/* always consider exact duplicates redundant */
 	foreach(refitem, reference_list)
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index 2c891c49644c72498400dc833997623ca23d8b18..cd8ced1307f798b5353a4c704c09cab86f12f86f 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.62 2004/01/07 18:56:26 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.63 2004/05/26 04:41:27 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -31,7 +31,7 @@
 TargetEntry *
 tlistentry_member(Node *node, List *targetlist)
 {
-	List	   *temp;
+	ListCell   *temp;
 
 	foreach(temp, targetlist)
 	{
@@ -138,11 +138,11 @@ List *
 add_to_flat_tlist(List *tlist, List *vars)
 {
 	int			next_resdomno = length(tlist) + 1;
-	List	   *v;
+	ListCell   *v;
 
 	foreach(v, vars)
 	{
-		Var		   *var = lfirst(v);
+		Var		   *var = (Var *) lfirst(v);
 
 		if (!tlistentry_member((Node *) var, tlist))
 		{
@@ -173,7 +173,7 @@ get_sortgroupclause_tle(SortClause *sortClause,
 						List *targetList)
 {
 	Index		refnumber = sortClause->tleSortGroupRef;
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, targetList)
 	{
@@ -212,7 +212,7 @@ List *
 get_sortgrouplist_exprs(List *sortClauses, List *targetList)
 {
 	List	   *result = NIL;
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, sortClauses)
 	{
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index 47b1fdbf70efc3c023370edb3fd201042b73f347..ecdc93ab7f516c030c39521b1d27999575defcef 100644
--- a/src/backend/optimizer/util/var.c
+++ b/src/backend/optimizer/util/var.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.56 2004/05/10 22:44:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.57 2004/05/26 04:41:27 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -513,9 +513,9 @@ flatten_join_alias_vars_mutator(Node *node,
 		if (var->varattno == InvalidAttrNumber)
 		{
 			/* Must expand whole-row reference */
-			RowExpr *rowexpr;
-			List	*fields = NIL;
-			List    *l;
+			RowExpr		*rowexpr;
+			List		*fields = NIL;
+			ListCell	*l;
 
 			foreach(l, rte->joinaliasvars)
 			{
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 2b1eddbcf09716e70af213abc2d11284e4267397..9da8937dc7bde08fd9f11d82a596f960d786e199 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.300 2004/05/23 17:10:54 tgl Exp $
+ *	$PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.301 2004/05/26 04:41:29 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -240,28 +240,20 @@ do_parse_analyze(Node *parseTree, ParseState *pstate)
 	List	   *extras_before = NIL;
 	List	   *extras_after = NIL;
 	Query	   *query;
-	List	   *listscan;
+	ListCell   *l;
 
 	query = transformStmt(pstate, parseTree, &extras_before, &extras_after);
 
 	/* don't need to access result relation any more */
 	release_pstate_resources(pstate);
 
-	while (extras_before != NIL)
-	{
-		result = nconc(result,
-					   parse_sub_analyze(lfirst(extras_before), pstate));
-		extras_before = lnext(extras_before);
-	}
+	foreach(l, extras_before)
+		result = nconc(result, parse_sub_analyze(lfirst(l), pstate));
 
 	result = lappend(result, query);
 
-	while (extras_after != NIL)
-	{
-		result = nconc(result,
-					   parse_sub_analyze(lfirst(extras_after), pstate));
-		extras_after = lnext(extras_after);
-	}
+	foreach(l, extras_after)
+		result = nconc(result, parse_sub_analyze(lfirst(l), pstate));
 
 	/*
 	 * Make sure that only the original query is marked original. We have
@@ -270,9 +262,9 @@ do_parse_analyze(Node *parseTree, ParseState *pstate)
 	 * mark only the original query as allowed to set the command-result
 	 * tag.
 	 */
-	foreach(listscan, result)
+	foreach(l, result)
 	{
-		Query	   *q = lfirst(listscan);
+		Query	   *q = lfirst(l);
 
 		if (q == query)
 		{
@@ -428,8 +420,8 @@ transformViewStmt(ParseState *pstate, ViewStmt *stmt,
 	 */
 	if (stmt->aliases != NIL)
 	{
-		List	   *aliaslist = stmt->aliases;
-		List	   *targetList;
+		ListCell	   *alist_item = list_head(stmt->aliases);
+		ListCell	   *targetList;
 
 		foreach(targetList, stmt->query->targetList)
 		{
@@ -442,13 +434,13 @@ transformViewStmt(ParseState *pstate, ViewStmt *stmt,
 			/* junk columns don't get aliases */
 			if (rd->resjunk)
 				continue;
-			rd->resname = pstrdup(strVal(lfirst(aliaslist)));
-			aliaslist = lnext(aliaslist);
-			if (aliaslist == NIL)
+			rd->resname = pstrdup(strVal(lfirst(alist_item)));
+			alist_item = lnext(alist_item);
+			if (alist_item == NULL)
 				break;		/* done assigning aliases */
 		}
 
-		if (aliaslist != NIL)
+		if (alist_item != NULL)
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
 					 errmsg("CREATE VIEW specifies more column "
@@ -506,9 +498,9 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
 	List	   *sub_namespace;
 	List	   *icolumns;
 	List	   *attrnos;
-	List	   *icols;			/* to become ListCell */
-	List	   *attnos;			/* to become ListCell */
-	List	   *tl;
+	ListCell   *icols;
+	ListCell   *attnos;
+	ListCell   *tl;
 
 	qry->commandType = CMD_INSERT;
 	pstate->p_is_insert = true;
@@ -666,14 +658,14 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
 	/*
 	 * Prepare columns for assignment to target table.
 	 */
-	icols = icolumns;
-	attnos = attrnos;
+	icols = list_head(icolumns);
+	attnos = list_head(attrnos);
 	foreach(tl, qry->targetList)
 	{
 		TargetEntry *tle = (TargetEntry *) lfirst(tl);
 		ResTarget  *col;
 
-		if (icols == NIL || attnos == NIL)
+		if (icols == NULL || attnos == NULL)
 			ereport(ERROR,
 					(errcode(ERRCODE_SYNTAX_ERROR),
 			 errmsg("INSERT has more expressions than target columns")));
@@ -694,7 +686,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
 	 * present in the columns list.  Don't do the check unless an explicit
 	 * columns list was given, though.
 	 */
-	if (stmt->cols != NIL && (icols != NIL || attnos != NIL))
+	if (stmt->cols != NIL && (icols != NULL || attnos != NULL))
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 			 errmsg("INSERT has more target columns than expressions")));
@@ -810,7 +802,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
 {
 	CreateStmtContext cxt;
 	Query	   *q;
-	List	   *elements;
+	ListCell   *elements;
 
 	cxt.stmtType = "CREATE TABLE";
 	cxt.relation = stmt->relation;
@@ -895,7 +887,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
 	bool		is_serial;
 	bool		saw_nullable;
 	Constraint *constraint;
-	List	   *clist;
+	ListCell   *clist;
 
 	cxt->columns = lappend(cxt->columns, column);
 
@@ -903,7 +895,7 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
 	is_serial = false;
 	if (length(column->typename->names) == 1)
 	{
-		char	   *typname = strVal(lfirst(column->typename->names));
+		char	   *typname = strVal(linitial(column->typename->names));
 
 		if (strcmp(typname, "serial") == 0 ||
 			strcmp(typname, "serial4") == 0)
@@ -1256,13 +1248,10 @@ transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
 static void
 transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
 {
-	List	   *listptr;
-	List	   *keys;
 	IndexStmt  *index;
-	IndexElem  *iparam;
-	ColumnDef  *column;
-	List	   *columns;
 	List	   *indexlist = NIL;
+	ListCell   *listptr;
+	ListCell   *l;
 
 	/*
 	 * Run through the constraints that need to generate an index. For
@@ -1273,6 +1262,8 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
 	foreach(listptr, cxt->ixconstraints)
 	{
 		Constraint *constraint = lfirst(listptr);
+		ListCell   *keys;
+		IndexElem  *iparam;
 
 		Assert(IsA(constraint, Constraint));
 		Assert((constraint->contype == CONSTR_PRIMARY)
@@ -1317,11 +1308,12 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
 		{
 			char	   *key = strVal(lfirst(keys));
 			bool		found = false;
+			ColumnDef  *column = NULL;
+			ListCell   *columns;
 
-			column = NULL;
 			foreach(columns, cxt->columns)
 			{
-				column = lfirst(columns);
+				column = (ColumnDef *) lfirst(columns);
 				Assert(IsA(column, ColumnDef));
 				if (strcmp(column->colname, key) == 0)
 				{
@@ -1347,11 +1339,11 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
 			else if (cxt->inhRelations)
 			{
 				/* try inherited tables */
-				List	   *inher;
+				ListCell   *inher;
 
 				foreach(inher, cxt->inhRelations)
 				{
-					RangeVar   *inh = lfirst(inher);
+					RangeVar   *inh = (RangeVar *) lfirst(inher);
 					Relation	rel;
 					int			count;
 
@@ -1447,41 +1439,40 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
 		/* Make sure we keep the PKEY index in preference to others... */
 		cxt->alist = makeList1(cxt->pkey);
 	}
-	while (indexlist != NIL)
+
+	foreach(l, indexlist)
 	{
-		index = lfirst(indexlist);
+		bool		keep = true;
+		ListCell   *k;
+
+		index = lfirst(l);
 
 		/* if it's pkey, it's already in cxt->alist */
-		if (index != cxt->pkey)
+		if (index == cxt->pkey)
+			continue;
+
+		foreach(k, cxt->alist)
 		{
-			bool		keep = true;
-			List	   *priorlist;
+			IndexStmt  *priorindex = lfirst(k);
 
-			foreach(priorlist, cxt->alist)
+			if (equal(index->indexParams, priorindex->indexParams))
 			{
-				IndexStmt  *priorindex = lfirst(priorlist);
-
-				if (equal(index->indexParams, priorindex->indexParams))
-				{
-					/*
-					 * If the prior index is as yet unnamed, and this one
-					 * is named, then transfer the name to the prior
-					 * index. This ensures that if we have named and
-					 * unnamed constraints, we'll use (at least one of)
-					 * the names for the index.
-					 */
-					if (priorindex->idxname == NULL)
-						priorindex->idxname = index->idxname;
-					keep = false;
-					break;
-				}
+				/*
+				 * If the prior index is as yet unnamed, and this one
+				 * is named, then transfer the name to the prior
+				 * index. This ensures that if we have named and
+				 * unnamed constraints, we'll use (at least one of)
+				 * the names for the index.
+				 */
+				if (priorindex->idxname == NULL)
+					priorindex->idxname = index->idxname;
+				keep = false;
+				break;
 			}
-
-			if (keep)
-				cxt->alist = lappend(cxt->alist, index);
 		}
 
-		indexlist = lnext(indexlist);
+		if (keep)
+			cxt->alist = lappend(cxt->alist, index);
 	}
 }
 
@@ -1489,7 +1480,7 @@ static void
 transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt,
 					   bool skipValidation, bool isAddConstraint)
 {
-	List	   *fkclist;
+	ListCell   *fkclist;
 
 	if (cxt->fkconstraints == NIL)
 		return;
@@ -1550,7 +1541,7 @@ transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
 {
 	Query	   *qry;
 	RangeTblEntry *rte = NULL;
-	List	   *l;
+	ListCell   *l;
 
 	qry = makeNode(Query);
 	qry->commandType = CMD_UTILITY;
@@ -1721,15 +1712,15 @@ transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
 	}
 	else
 	{
-		List	   *oldactions;
+		ListCell   *l;
 		List	   *newactions = NIL;
 
 		/*
 		 * transform each statement, like parse_sub_analyze()
 		 */
-		foreach(oldactions, stmt->actions)
+		foreach(l, stmt->actions)
 		{
-			Node	   *action = (Node *) lfirst(oldactions);
+			Node	   *action = (Node *) lfirst(l);
 			ParseState *sub_pstate = make_parsestate(pstate->parentParseState);
 			Query	   *sub_qry,
 					   *top_subqry;
@@ -1986,9 +1977,9 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
 	Node	   *limitCount;
 	List	   *forUpdate;
 	Node	   *node;
-	List	   *lefttl,
-			   *dtlist,
-			   *targetvars,
+	ListCell   *left_tlist,
+			   *dtlist;
+	List	   *targetvars,
 			   *targetnames,
 			   *sv_namespace,
 			   *sv_rtable;
@@ -2067,15 +2058,17 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
 	qry->targetList = NIL;
 	targetvars = NIL;
 	targetnames = NIL;
-	lefttl = leftmostQuery->targetList;
+	left_tlist = list_head(leftmostQuery->targetList);
+
 	foreach(dtlist, sostmt->colTypes)
 	{
 		Oid			colType = lfirsto(dtlist);
-		Resdom	   *leftResdom = ((TargetEntry *) lfirst(lefttl))->resdom;
+		Resdom	   *leftResdom;
 		char	   *colName;
 		Resdom	   *resdom;
 		Expr	   *expr;
 
+		leftResdom = ((TargetEntry *) lfirst(left_tlist))->resdom;
 		Assert(!leftResdom->resjunk);
 		colName = pstrdup(leftResdom->resname);
 		resdom = makeResdom((AttrNumber) pstate->p_next_resno++,
@@ -2092,7 +2085,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
 								  makeTargetEntry(resdom, expr));
 		targetvars = lappend(targetvars, expr);
 		targetnames = lappend(targetnames, makeString(colName));
-		lefttl = lnext(lefttl);
+		left_tlist = lnext(left_tlist);
 	}
 
 	/*
@@ -2239,7 +2232,7 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
 		selectList = parse_sub_analyze((Node *) stmt, pstate);
 
 		Assert(length(selectList) == 1);
-		selectQuery = (Query *) lfirst(selectList);
+		selectQuery = (Query *) linitial(selectList);
 		Assert(IsA(selectQuery, Query));
 
 		/*
@@ -2282,6 +2275,8 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
 		SetOperationStmt *op = makeNode(SetOperationStmt);
 		List	   *lcoltypes;
 		List	   *rcoltypes;
+		ListCell   *l;
+		ListCell   *r;
 		const char *context;
 
 		context = (stmt->op == SETOP_UNION ? "UNION" :
@@ -2308,18 +2303,17 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
 					(errcode(ERRCODE_SYNTAX_ERROR),
 			 errmsg("each %s query must have the same number of columns",
 					context)));
+
 		op->colTypes = NIL;
-		while (lcoltypes != NIL)
+		forboth(l, lcoltypes, r, rcoltypes)
 		{
-			Oid			lcoltype = lfirsto(lcoltypes);
-			Oid			rcoltype = lfirsto(rcoltypes);
+			Oid			lcoltype = lfirsto(l);
+			Oid			rcoltype = lfirsto(r);
 			Oid			rescoltype;
 
 			rescoltype = select_common_type(makeListo2(lcoltype, rcoltype),
 											context);
 			op->colTypes = lappendo(op->colTypes, rescoltype);
-			lcoltypes = lnext(lcoltypes);
-			rcoltypes = lnext(rcoltypes);
 		}
 
 		return (Node *) op;
@@ -2339,7 +2333,7 @@ getSetColTypes(ParseState *pstate, Node *node)
 		RangeTblEntry *rte = rt_fetch(rtr->rtindex, pstate->p_rtable);
 		Query	   *selectQuery = rte->subquery;
 		List	   *result = NIL;
-		List	   *tl;
+		ListCell   *tl;
 
 		Assert(selectQuery != NULL);
 		/* Get types of non-junk columns */
@@ -2373,22 +2367,25 @@ getSetColTypes(ParseState *pstate, Node *node)
 static void
 applyColumnNames(List *dst, List *src)
 {
+	ListCell *dst_item = list_head(dst);
+	ListCell *src_item = list_head(src);
+
 	if (length(src) > length(dst))
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 			 errmsg("CREATE TABLE AS specifies too many column names")));
 
-	while (src != NIL && dst != NIL)
+	while (src_item != NULL && dst_item != NULL)
 	{
-		TargetEntry *d = (TargetEntry *) lfirst(dst);
-		ColumnDef  *s = (ColumnDef *) lfirst(src);
+		TargetEntry *d = (TargetEntry *) lfirst(dst_item);
+		ColumnDef  *s = (ColumnDef *) lfirst(src_item);
 
 		Assert(d->resdom && !d->resdom->resjunk);
 
 		d->resdom->resname = pstrdup(s->colname);
 
-		dst = lnext(dst);
-		src = lnext(src);
+		dst_item = lnext(dst_item);
+		src_item = lnext(src_item);
 	}
 }
 
@@ -2402,8 +2399,8 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
 {
 	Query	   *qry = makeNode(Query);
 	Node	   *qual;
-	List	   *origTargetList;
-	List	   *tl;
+	ListCell   *origTargetList;
+	ListCell   *tl;
 
 	qry->commandType = CMD_UPDATE;
 	pstate->p_is_update = true;
@@ -2441,7 +2438,8 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
 		pstate->p_next_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
 
 	/* Prepare non-junk columns for assignment to target table */
-	origTargetList = stmt->targetList;
+	origTargetList = list_head(stmt->targetList);
+
 	foreach(tl, qry->targetList)
 	{
 		TargetEntry *tle = (TargetEntry *) lfirst(tl);
@@ -2460,7 +2458,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
 			resnode->resname = NULL;
 			continue;
 		}
-		if (origTargetList == NIL)
+		if (origTargetList == NULL)
 			elog(ERROR, "UPDATE target count mismatch --- internal error");
 		origTarget = (ResTarget *) lfirst(origTargetList);
 
@@ -2471,7 +2469,7 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
 
 		origTargetList = lnext(origTargetList);
 	}
-	if (origTargetList != NIL)
+	if (origTargetList != NULL)
 		elog(ERROR, "UPDATE target count mismatch --- internal error");
 
 	return qry;
@@ -2487,7 +2485,7 @@ transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
 {
 	CreateStmtContext cxt;
 	Query	   *qry;
-	List	   *lcmd,
+	ListCell   *lcmd,
 			   *l;
 	List	   *newcmds = NIL;
 	bool		skipValidation = true;
@@ -2687,7 +2685,7 @@ transformPrepareStmt(ParseState *pstate, PrepareStmt *stmt)
 
 	if (nargs)
 	{
-		List	   *l;
+		ListCell   *l;
 		int			i = 0;
 
 		argtoids = (Oid *) palloc(nargs * sizeof(Oid));
@@ -2717,7 +2715,7 @@ transformPrepareStmt(ParseState *pstate, PrepareStmt *stmt)
 	if (length(queries) != 1)
 		elog(ERROR, "unexpected extra stuff in prepared statement");
 
-	stmt->query = lfirst(queries);
+	stmt->query = linitial(queries);
 
 	return result;
 }
@@ -2737,7 +2735,7 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
 	{
 		int			nparams = length(stmt->params);
 		int			nexpected = length(paramtypes);
-		List	   *l;
+		ListCell   *l, *l2;
 		int			i = 1;
 
 		if (nparams != nexpected)
@@ -2748,11 +2746,11 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
 					 errdetail("Expected %d parameters but got %d.",
 							   nexpected, nparams)));
 
-		foreach(l, stmt->params)
+		forboth(l, stmt->params, l2, paramtypes)
 		{
 			Node	   *expr = lfirst(l);
-			Oid			expected_type_id,
-						given_type_id;
+			Oid			expected_type_id = lfirsto(l2);
+			Oid			given_type_id;
 
 			expr = transformExpr(pstate, expr);
 
@@ -2767,7 +2765,6 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
 				   errmsg("cannot use aggregate function in EXECUTE parameter")));
 
 			given_type_id = exprType(expr);
-			expected_type_id = lfirsto(paramtypes);
 
 			expr = coerce_to_target_type(pstate, expr, given_type_id,
 										 expected_type_id, -1,
@@ -2784,8 +2781,6 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
 						 errhint("You will need to rewrite or cast the expression.")));
 
 			lfirst(l) = expr;
-
-			paramtypes = lnext(paramtypes);
 			i++;
 		}
 	}
@@ -2825,13 +2820,13 @@ static void
 transformForUpdate(Query *qry, List *forUpdate)
 {
 	List	   *rowMarks = qry->rowMarks;
-	List	   *l;
-	List	   *rt;
+	ListCell   *l;
+	ListCell   *rt;
 	Index		i;
 
 	CheckSelectForUpdate(qry);
 
-	if (lfirst(forUpdate) == NULL)
+	if (linitial(forUpdate) == NULL)
 	{
 		/* all regular tables used in query */
 		i = 0;
@@ -2912,7 +2907,7 @@ transformForUpdate(Query *qry, List *forUpdate)
 					break;		/* out of foreach loop */
 				}
 			}
-			if (rt == NIL)
+			if (rt == NULL)
 				ereport(ERROR,
 						(errcode(ERRCODE_UNDEFINED_TABLE),
 						 errmsg("relation \"%s\" in FOR UPDATE clause not found in FROM clause",
@@ -2938,7 +2933,7 @@ transformConstraintAttrs(List *constraintList)
 	Node	   *lastprimarynode = NULL;
 	bool		saw_deferrability = false;
 	bool		saw_initially = false;
-	List	   *clist;
+	ListCell   *clist;
 
 	foreach(clist, constraintList)
 	{
@@ -3113,7 +3108,7 @@ analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
 {
 	CreateSchemaStmtContext cxt;
 	List	   *result;
-	List	   *elements;
+	ListCell   *elements;
 
 	cxt.stmtType = "CREATE SCHEMA";
 	cxt.schemaname = stmt->schemaname;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b9becf91dbb908f52d0cfc966a217d2a1c8dc7a5..654341ddfe816f3fe773b79b4d9ab99f448cc31d 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.454 2004/05/10 22:44:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.455 2004/05/26 04:41:29 neilc Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -2385,15 +2385,15 @@ DefineStmt:
 						case 1:
 							r->catalogname = NULL;
 							r->schemaname = NULL;
-							r->relname = strVal(lfirst($3));
+							r->relname = strVal(linitial($3));
 							break;
 						case 2:
 							r->catalogname = NULL;
-							r->schemaname = strVal(lfirst($3));
+							r->schemaname = strVal(linitial($3));
 							r->relname = strVal(lsecond($3));
 							break;
 						case 3:
-							r->catalogname = strVal(lfirst($3));
+							r->catalogname = strVal(linitial($3));
 							r->schemaname = strVal(lsecond($3));
 							r->relname = strVal(lthird($3));
 							break;
@@ -6020,7 +6020,7 @@ a_expr:		c_expr									{ $$ = $1; }
 					else
 					{
 						Node *n = NULL;
-						List *l;
+						ListCell *l;
 						foreach(l, (List *) $3)
 						{
 							Node *cmp;
@@ -6052,7 +6052,7 @@ a_expr:		c_expr									{ $$ = $1; }
 					else
 					{
 						Node *n = NULL;
-						List *l;
+						ListCell *l;
 						foreach(l, (List *) $4)
 						{
 							Node *cmp;
@@ -7168,11 +7168,11 @@ qualified_name:
 					{
 						case 2:
 							$$->catalogname = NULL;
-							$$->schemaname = strVal(lfirst($1));
+							$$->schemaname = strVal(linitial($1));
 							$$->relname = strVal(lsecond($1));
 							break;
 						case 3:
-							$$->catalogname = strVal(lfirst($1));
+							$$->catalogname = strVal(linitial($1));
 							$$->schemaname = strVal(lsecond($1));
 							$$->relname = strVal(lthird($1));
 							break;
@@ -7864,8 +7864,8 @@ makeBoolAConst(bool state)
 static Node *
 makeRowNullTest(NullTestType test, RowExpr *row)
 {
-	Node	*result = NULL;
-	List	*arg;
+	Node		*result = NULL;
+	ListCell	*arg;
 
 	foreach(arg, row->args)
 	{
@@ -7928,7 +7928,7 @@ static List *
 extractArgTypes(List *parameters)
 {
 	List	   *result = NIL;
-	List	   *i;
+	ListCell   *i;
 
 	foreach(i, parameters)
 	{
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index 6f85595610d5c546987d0cd1d792ef79df502195..e9c73ee946aaafa15e3a89e26860a2b477825939 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.61 2004/01/28 07:46:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.62 2004/05/26 04:41:29 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -99,7 +99,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
 {
 	List	   *groupClauses = NIL;
 	bool		have_non_var_grouping;
-	List	   *lst;
+	ListCell   *l;
 	bool		hasJoinRTEs;
 	Node	   *clause;
 
@@ -129,9 +129,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
 	 * While we are at it, build a list of the acceptable GROUP BY
 	 * expressions for use by check_ungrouped_columns().
 	 */
-	foreach(lst, qry->groupClause)
+	foreach(l, qry->groupClause)
 	{
-		GroupClause *grpcl = (GroupClause *) lfirst(lst);
+		GroupClause *grpcl = (GroupClause *) lfirst(l);
 		Node	   *expr;
 
 		expr = get_sortgroupclause_expr(grpcl, qry->targetList);
@@ -151,9 +151,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
 	 * no rangetable entries are RTE_JOIN kind.
 	 */
 	hasJoinRTEs = false;
-	foreach(lst, pstate->p_rtable)
+	foreach(l, pstate->p_rtable)
 	{
-		RangeTblEntry *rte = (RangeTblEntry *) lfirst(lst);
+		RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
 
 		if (rte->rtekind == RTE_JOIN)
 		{
@@ -172,9 +172,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
 	 * recursive scans.  (Note we have to flatten aliases before this.)
 	 */
 	have_non_var_grouping = false;
-	foreach(lst, groupClauses)
+	foreach(l, groupClauses)
 	{
-		if (!IsA((Node *) lfirst(lst), Var))
+		if (!IsA((Node *) lfirst(l), Var))
 		{
 			have_non_var_grouping = true;
 			break;
@@ -236,7 +236,7 @@ static bool
 check_ungrouped_columns_walker(Node *node,
 							   check_ungrouped_columns_context *context)
 {
-	List	   *gl;
+	ListCell   *gl;
 
 	if (node == NULL)
 		return false;
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 2c6e99428997906ac90522481034d39d65d58ee4..610c4fa2960796efb8cbf0c118beea1180eaa30a 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.129 2004/05/23 17:10:54 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.130 2004/05/26 04:41:29 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -79,7 +79,7 @@ static TargetEntry *findTargetlistEntry(ParseState *pstate, Node *node,
 void
 transformFromClause(ParseState *pstate, List *frmList)
 {
-	List	   *fl;
+	ListCell   *fl;
 
 	/*
 	 * The grammar will have produced a list of RangeVars,
@@ -231,14 +231,15 @@ extractRemainingColumns(List *common_colnames,
 {
 	List	   *new_colnames = NIL;
 	List	   *new_colvars = NIL;
-	List	   *lnames,
-			   *lvars = src_colvars;
+	ListCell   *lnames, *lvars;
 
-	foreach(lnames, src_colnames)
+	Assert(length(src_colnames) == length(src_colvars));
+
+	forboth(lnames, src_colnames, lvars, src_colvars)
 	{
 		char	   *colname = strVal(lfirst(lnames));
 		bool		match = false;
-		List	   *cnames;
+		ListCell   *cnames;
 
 		foreach(cnames, common_colnames)
 		{
@@ -256,8 +257,6 @@ extractRemainingColumns(List *common_colnames,
 			new_colnames = lappend(new_colnames, lfirst(lnames));
 			new_colvars = lappend(new_colvars, lfirst(lvars));
 		}
-
-		lvars = lnext(lvars);
 	}
 
 	*res_colnames = new_colnames;
@@ -273,8 +272,7 @@ static Node *
 transformJoinUsingClause(ParseState *pstate, List *leftVars, List *rightVars)
 {
 	Node	   *result = NULL;
-	List	   *lvars,
-			   *rvars = rightVars;
+	ListCell   *lvars, *rvars;
 
 	/*
 	 * We cheat a little bit here by building an untransformed operator
@@ -282,7 +280,7 @@ transformJoinUsingClause(ParseState *pstate, List *leftVars, List *rightVars)
 	 * because transformExpr() won't complain about already-transformed
 	 * subnodes.
 	 */
-	foreach(lvars, leftVars)
+	forboth(lvars, leftVars, rvars, rightVars)
 	{
 		Node	   *lvar = (Node *) lfirst(lvars);
 		Node	   *rvar = (Node *) lfirst(rvars);
@@ -299,8 +297,6 @@ transformJoinUsingClause(ParseState *pstate, List *leftVars, List *rightVars)
 			a = makeA_Expr(AEXPR_AND, NIL, result, (Node *) e);
 			result = (Node *) a;
 		}
-
-		rvars = lnext(rvars);
 	}
 
 	/*
@@ -314,7 +310,7 @@ transformJoinUsingClause(ParseState *pstate, List *leftVars, List *rightVars)
 	result = coerce_to_boolean(pstate, result, "JOIN/USING");
 
 	return result;
-}	/* transformJoinUsingClause() */
+}
 
 /* transformJoinOnClause()
  *	  Transform the qual conditions for JOIN/ON.
@@ -435,7 +431,7 @@ transformRangeSubselect(ParseState *pstate, RangeSubselect *r)
 	 */
 	if (length(parsetrees) != 1)
 		elog(ERROR, "unexpected parse analysis result for subquery in FROM");
-	query = (Query *) lfirst(parsetrees);
+	query = (Query *) linitial(parsetrees);
 	if (query == NULL || !IsA(query, Query))
 		elog(ERROR, "unexpected parse analysis result for subquery in FROM");
 
@@ -686,7 +682,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, List **containedRels)
 		if (j->isNatural)
 		{
 			List	   *rlist = NIL;
-			List	   *lx,
+			ListCell   *lx,
 					   *rx;
 
 			Assert(j->using == NIL);	/* shouldn't have USING() too */
@@ -731,14 +727,14 @@ transformFromClauseItem(ParseState *pstate, Node *n, List **containedRels)
 			List	   *ucols = j->using;
 			List	   *l_usingvars = NIL;
 			List	   *r_usingvars = NIL;
-			List	   *ucol;
+			ListCell   *ucol;
 
 			Assert(j->quals == NULL);	/* shouldn't have ON() too */
 
 			foreach(ucol, ucols)
 			{
 				char	   *u_colname = strVal(lfirst(ucol));
-				List	   *col;
+				ListCell   *col;
 				int			ndx;
 				int			l_index = -1;
 				int			r_index = -1;
@@ -1083,7 +1079,7 @@ static TargetEntry *
 findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
 {
 	TargetEntry *target_result = NULL;
-	List	   *tl;
+	ListCell   *tl;
 	Node	   *expr;
 
 	/*----------
@@ -1129,7 +1125,7 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
 		length(((ColumnRef *) node)->fields) == 1 &&
 		((ColumnRef *) node)->indirection == NIL)
 	{
-		char	   *name = strVal(lfirst(((ColumnRef *) node)->fields));
+		char	   *name = strVal(linitial(((ColumnRef *) node)->fields));
 
 		if (clause == GROUP_CLAUSE)
 		{
@@ -1255,8 +1251,11 @@ List *
 transformGroupClause(ParseState *pstate, List *grouplist,
 					 List **targetlist, List *sortClause)
 {
-	List	   *glist = NIL,
-			   *gl;
+	List	   *glist = NIL;
+	ListCell   *gl;
+	ListCell   *sortItem;
+
+	sortItem = list_head(sortClause);
 
 	foreach(gl, grouplist)
 	{
@@ -1293,17 +1292,17 @@ transformGroupClause(ParseState *pstate, List *grouplist,
 		 * any user-supplied ordering operator will bring equal values
 		 * together, which is all that GROUP BY needs.
 		 */
-		if (sortClause &&
-			((SortClause *) lfirst(sortClause))->tleSortGroupRef ==
+		if (sortItem &&
+			((SortClause *) lfirst(sortItem))->tleSortGroupRef ==
 			tle->resdom->ressortgroupref)
 		{
-			ordering_op = ((SortClause *) lfirst(sortClause))->sortop;
-			sortClause = lnext(sortClause);
+			ordering_op = ((SortClause *) lfirst(sortItem))->sortop;
+			sortItem = lnext(sortItem);
 		}
 		else
 		{
 			ordering_op = ordering_oper_opid(restype);
-			sortClause = NIL;	/* disregard ORDER BY once match fails */
+			sortItem = NULL;	/* disregard ORDER BY once match fails */
 		}
 
 		grpcl = makeNode(GroupClause);
@@ -1329,7 +1328,7 @@ transformSortClause(ParseState *pstate,
 					bool resolveUnknown)
 {
 	List	   *sortlist = NIL;
-	List	   *olitem;
+	ListCell   *olitem;
 
 	foreach(olitem, orderlist)
 	{
@@ -1361,14 +1360,14 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
 						List **targetlist, List **sortClause)
 {
 	List	   *result = NIL;
-	List	   *slitem;
-	List	   *dlitem;
+	ListCell   *slitem;
+	ListCell   *dlitem;
 
 	/* No work if there was no DISTINCT clause */
 	if (distinctlist == NIL)
 		return NIL;
 
-	if (lfirst(distinctlist) == NIL)
+	if (linitial(distinctlist) == NULL)
 	{
 		/* We had SELECT DISTINCT */
 
@@ -1423,7 +1422,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
 		 * match in any order, but implementing that check seems like more
 		 * trouble than it's worth.
 		 */
-		List	   *nextsortlist = *sortClause;
+		ListCell   *nextsortlist = list_head(*sortClause);
 
 		foreach(dlitem, distinctlist)
 		{
@@ -1432,7 +1431,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
 			tle = findTargetlistEntry(pstate, lfirst(dlitem),
 									  targetlist, DISTINCT_ON_CLAUSE);
 
-			if (nextsortlist != NIL)
+			if (nextsortlist != NULL)
 			{
 				SortClause *scl = (SortClause *) lfirst(nextsortlist);
 
@@ -1463,7 +1462,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
 						break;
 					}
 				}
-				if (slitem == NIL)		/* should not happen */
+				if (slitem == NULL)		/* should not happen */
 					elog(ERROR, "failed to add DISTINCT ON clause to target list");
 			}
 		}
@@ -1486,11 +1485,11 @@ List *
 addAllTargetsToSortList(ParseState *pstate, List *sortlist,
 						List *targetlist, bool resolveUnknown)
 {
-	List	   *i;
+	ListCell  *l;
 
-	foreach(i, targetlist)
+	foreach(l, targetlist)
 	{
-		TargetEntry *tle = (TargetEntry *) lfirst(i);
+		TargetEntry *tle = (TargetEntry *) lfirst(l);
 
 		if (!tle->resdom->resjunk)
 			sortlist = addTargetToSortList(pstate, tle,
@@ -1575,7 +1574,7 @@ Index
 assignSortGroupRef(TargetEntry *tle, List *tlist)
 {
 	Index		maxRef;
-	List	   *l;
+	ListCell   *l;
 
 	if (tle->resdom->ressortgroupref)	/* already has one? */
 		return tle->resdom->ressortgroupref;
@@ -1605,15 +1604,15 @@ bool
 targetIsInSortList(TargetEntry *tle, List *sortList)
 {
 	Index		ref = tle->resdom->ressortgroupref;
-	List	   *i;
+	ListCell   *l;
 
 	/* no need to scan list if tle has no marker */
 	if (ref == 0)
 		return false;
 
-	foreach(i, sortList)
+	foreach(l, sortList)
 	{
-		SortClause *scl = (SortClause *) lfirst(i);
+		SortClause *scl = (SortClause *) lfirst(l);
 
 		if (scl->tleSortGroupRef == ref)
 			return true;
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index c7a8c3c83bbd27413a33755eebe0feff19a7daff..ba3210946abf9f23b04bdca243b34cdadc98b213 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.115 2004/05/10 22:44:46 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.116 2004/05/26 04:41:30 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -546,7 +546,7 @@ coerce_record_to_complex(ParseState *pstate, Node *node,
 	List	   *args = NIL;
 	List	   *newargs;
 	int			i;
-	List	   *arg;
+	ListCell   *arg;
 
 	if (node && IsA(node, RowExpr))
 	{
@@ -720,14 +720,15 @@ select_common_type(List *typeids, const char *context)
 {
 	Oid			ptype;
 	CATEGORY	pcategory;
-	List	   *l;
+	ListCell   *type_item;
 
 	Assert(typeids != NIL);
-	ptype = getBaseType(lfirsto(typeids));
+	ptype = getBaseType(linitial_oid(typeids));
 	pcategory = TypeCategory(ptype);
-	foreach(l, lnext(typeids))
+
+	for_each_cell(type_item, lnext(list_head(typeids)))
 	{
-		Oid			ntype = getBaseType(lfirsto(l));
+		Oid			ntype = getBaseType(lfirsto(type_item));
 
 		/* move on to next one if no new information... */
 		if ((ntype != InvalidOid) && (ntype != UNKNOWNOID) && (ntype != ptype))
@@ -746,7 +747,6 @@ select_common_type(List *typeids, const char *context)
 				 */
 				ereport(ERROR,
 						(errcode(ERRCODE_DATATYPE_MISMATCH),
-
 				/*
 				 * translator: first %s is name of a SQL construct, eg
 				 * CASE
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index d4a8cdcc8b64999933be2a1bb078a861927bdf75..9efebdfdb483f822275bf37b3eda4cf0c149b164 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.170 2004/05/10 22:44:46 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.171 2004/05/26 04:41:30 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -100,7 +100,7 @@ transformExpr(ParseState *pstate, Node *expr)
 				int			paramno = pref->number;
 				ParseState *toppstate;
 				Param	   *param;
-				List	   *fields;
+				ListCell   *fields;
 
 				/*
 				 * Find topmost ParseState, which is where paramtype info
@@ -176,7 +176,7 @@ transformExpr(ParseState *pstate, Node *expr)
 		case T_ExprFieldSelect:
 			{
 				ExprFieldSelect *efs = (ExprFieldSelect *) expr;
-				List	   *fields;
+				ListCell	    *fields;
 
 				result = transformExpr(pstate, efs->arg);
 				/* handle qualification, if any */
@@ -219,7 +219,7 @@ transformExpr(ParseState *pstate, Node *expr)
 							 */
 							if (Transform_null_equals &&
 								length(a->name) == 1 &&
-							 strcmp(strVal(lfirst(a->name)), "=") == 0 &&
+								strcmp(strVal(linitial(a->name)), "=") == 0 &&
 								(exprIsNullConstant(lexpr) ||
 								 exprIsNullConstant(rexpr)))
 							{
@@ -396,7 +396,7 @@ transformExpr(ParseState *pstate, Node *expr)
 							 * Checking an expression for match to type.
 							 * Will result in a boolean constant node.
 							 */
-							List	   *telem;
+							ListCell   *telem;
 							A_Const    *n;
 							Oid			ltype,
 										rtype;
@@ -418,7 +418,7 @@ transformExpr(ParseState *pstate, Node *expr)
 							 * Flip the sense of the result for not
 							 * equals.
 							 */
-							if (strcmp(strVal(lfirst(a->name)), "!=") == 0)
+							if (strcmp(strVal(linitial(a->name)), "!=") == 0)
 								matched = (!matched);
 
 							n = makeNode(A_Const);
@@ -436,12 +436,15 @@ transformExpr(ParseState *pstate, Node *expr)
 			{
 				FuncCall   *fn = (FuncCall *) expr;
 				List	   *targs;
-				List	   *args;
+				ListCell   *args;
 
 				/*
 				 * Transform the list of arguments.  We use a shallow list
 				 * copy and then transform-in-place to avoid O(N^2)
 				 * behavior from repeated lappend's.
+				 *
+				 * XXX: repeated lappend() would no longer result in
+				 * O(n^2) behavior; worth reconsidering this design?
 				 */
 				targs = listCopy(fn->args);
 				foreach(args, targs)
@@ -473,7 +476,7 @@ transformExpr(ParseState *pstate, Node *expr)
 				qtrees = parse_sub_analyze(sublink->subselect, pstate);
 				if (length(qtrees) != 1)
 					elog(ERROR, "bad query in sub-select");
-				qtree = (Query *) lfirst(qtrees);
+				qtree = (Query *) linitial(qtrees);
 				if (qtree->commandType != CMD_SELECT ||
 					qtree->resultRelation != 0)
 					elog(ERROR, "bad query in sub-select");
@@ -493,20 +496,20 @@ transformExpr(ParseState *pstate, Node *expr)
 				else if (sublink->subLinkType == EXPR_SUBLINK ||
 						 sublink->subLinkType == ARRAY_SUBLINK)
 				{
-					List	   *tlist = qtree->targetList;
+					ListCell   *tlist_item = list_head(qtree->targetList);
 
 					/*
 					 * Make sure the subselect delivers a single column
 					 * (ignoring resjunk targets).
 					 */
-					if (tlist == NIL ||
-						((TargetEntry *) lfirst(tlist))->resdom->resjunk)
+					if (tlist_item == NULL ||
+						((TargetEntry *) lfirst(tlist_item))->resdom->resjunk)
 						ereport(ERROR,
 								(errcode(ERRCODE_SYNTAX_ERROR),
 							 errmsg("subquery must return a column")));
-					while ((tlist = lnext(tlist)) != NIL)
+					while ((tlist_item = lnext(tlist_item)) != NULL)
 					{
-						if (!((TargetEntry *) lfirst(tlist))->resdom->resjunk)
+						if (!((TargetEntry *) lfirst(tlist_item))->resdom->resjunk)
 							ereport(ERROR,
 									(errcode(ERRCODE_SYNTAX_ERROR),
 									 errmsg("subquery must return only one column")));
@@ -531,11 +534,12 @@ transformExpr(ParseState *pstate, Node *expr)
 					bool		needNot = false;
 					List	   *op = sublink->operName;
 					char	   *opname = strVal(llast(op));
-					List	   *elist;
+					ListCell   *l;
+					ListCell   *ll_item;
 
 					/* transform lefthand expressions */
-					foreach(elist, left_list)
-						lfirst(elist) = transformExpr(pstate, lfirst(elist));
+					foreach(l, left_list)
+						lfirst(l) = transformExpr(pstate, lfirst(l));
 
 					/*
 					 * If the expression is "<> ALL" (with unqualified
@@ -578,23 +582,23 @@ transformExpr(ParseState *pstate, Node *expr)
 					 */
 					sublink->operOids = NIL;
 
-					while (right_list != NIL)
+					ll_item = list_head(left_list);
+					foreach(l, right_list)
 					{
-						TargetEntry *tent = (TargetEntry *) lfirst(right_list);
+						TargetEntry *tent = (TargetEntry *) lfirst(l);
 						Node	   *lexpr;
 						Operator	optup;
 						Form_pg_operator opform;
 
-						right_list = lnext(right_list);
 						if (tent->resdom->resjunk)
 							continue;
 
-						if (left_list == NIL)
+						if (ll_item == NULL)
 							ereport(ERROR,
 									(errcode(ERRCODE_SYNTAX_ERROR),
 							 errmsg("subquery has too many columns")));
-						lexpr = lfirst(left_list);
-						left_list = lnext(left_list);
+						lexpr = lfirst(ll_item);
+						ll_item = lnext(ll_item);
 
 						/*
 						 * It's OK to use oper() not compatible_oper()
@@ -627,7 +631,7 @@ transformExpr(ParseState *pstate, Node *expr)
 
 						ReleaseSysCache(optup);
 					}
-					if (left_list != NIL)
+					if (ll_item != NULL)
 						ereport(ERROR,
 								(errcode(ERRCODE_SYNTAX_ERROR),
 							  errmsg("subquery has too few columns")));
@@ -651,7 +655,7 @@ transformExpr(ParseState *pstate, Node *expr)
 				CaseTestExpr *placeholder;
 				List	   *newargs;
 				List	   *typeids;
-				List	   *args;
+				ListCell   *l;
 				Node	   *defresult;
 				Oid			ptype;
 
@@ -679,9 +683,9 @@ transformExpr(ParseState *pstate, Node *expr)
 				/* transform the list of arguments */
 				newargs = NIL;
 				typeids = NIL;
-				foreach(args, c->args)
+				foreach(l, c->args)
 				{
-					CaseWhen   *w = (CaseWhen *) lfirst(args);
+					CaseWhen   *w = (CaseWhen *) lfirst(l);
 					CaseWhen   *neww = makeNode(CaseWhen);
 					Node	   *warg;
 
@@ -741,9 +745,9 @@ transformExpr(ParseState *pstate, Node *expr)
 										  "CASE/ELSE");
 
 				/* Convert when-clause results, if necessary */
-				foreach(args, newc->args)
+				foreach(l, newc->args)
 				{
-					CaseWhen   *w = (CaseWhen *) lfirst(args);
+					CaseWhen   *w = (CaseWhen *) lfirst(l);
 
 					w->result = (Expr *)
 						coerce_to_common_type(pstate,
@@ -763,7 +767,7 @@ transformExpr(ParseState *pstate, Node *expr)
 				List	   *newelems = NIL;
 				List	   *newcoercedelems = NIL;
 				List	   *typeids = NIL;
-				List	   *element;
+				ListCell   *element;
 				Oid			array_type;
 				Oid			element_type;
 
@@ -827,7 +831,7 @@ transformExpr(ParseState *pstate, Node *expr)
 				RowExpr	   *r = (RowExpr *) expr;
 				RowExpr	   *newr = makeNode(RowExpr);
 				List	   *newargs = NIL;
-				List	   *arg;
+				ListCell   *arg;
 
 				/* Transform the field expressions */
 				foreach(arg, r->args)
@@ -855,7 +859,7 @@ transformExpr(ParseState *pstate, Node *expr)
 				List	   *newargs = NIL;
 				List	   *newcoercedargs = NIL;
 				List	   *typeids = NIL;
-				List	   *args;
+				ListCell   *args;
 
 				foreach(args, c->args)
 				{
@@ -1024,7 +1028,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
 	{
 		case 1:
 			{
-				char	   *name = strVal(lfirst(cref->fields));
+				char	   *name = strVal(linitial(cref->fields));
 
 				/* Try to identify as an unqualified column */
 				node = colNameToVar(pstate, name, false);
@@ -1070,7 +1074,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
 			}
 		case 2:
 			{
-				char	   *name1 = strVal(lfirst(cref->fields));
+				char	   *name1 = strVal(linitial(cref->fields));
 				char	   *name2 = strVal(lsecond(cref->fields));
 
 				/* Whole-row reference? */
@@ -1099,7 +1103,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
 			}
 		case 3:
 			{
-				char	   *name1 = strVal(lfirst(cref->fields));
+				char	   *name1 = strVal(linitial(cref->fields));
 				char	   *name2 = strVal(lsecond(cref->fields));
 				char	   *name3 = strVal(lthird(cref->fields));
 
@@ -1125,7 +1129,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref)
 			}
 		case 4:
 			{
-				char	   *name1 = strVal(lfirst(cref->fields));
+				char	   *name1 = strVal(linitial(cref->fields));
 				char	   *name2 = strVal(lsecond(cref->fields));
 				char	   *name3 = strVal(lthird(cref->fields));
 				char	   *name4 = strVal(lfourth(cref->fields));
@@ -1316,7 +1320,7 @@ exprType(Node *expr)
 
 					if (!qtree || !IsA(qtree, Query))
 						elog(ERROR, "cannot get type for untransformed sublink");
-					tent = (TargetEntry *) lfirst(qtree->targetList);
+					tent = (TargetEntry *) linitial(qtree->targetList);
 					Assert(IsA(tent, TargetEntry));
 					Assert(!tent->resdom->resjunk);
 					if (sublink->subLinkType == EXPR_SUBLINK)
@@ -1355,7 +1359,7 @@ exprType(Node *expr)
 					/* get the type of the subselect's first target column */
 					TargetEntry *tent;
 
-					tent = (TargetEntry *) lfirst(subplan->plan->targetlist);
+					tent = (TargetEntry *) linitial(subplan->plan->targetlist);
 					Assert(IsA(tent, TargetEntry));
 					Assert(!tent->resdom->resjunk);
 					if (subplan->subLinkType == EXPR_SUBLINK)
@@ -1403,7 +1407,7 @@ exprType(Node *expr)
 			type = ((CoalesceExpr *) expr)->coalescetype;
 			break;
 		case T_NullIfExpr:
-			type = exprType((Node *) lfirst(((NullIfExpr *) expr)->args));
+			type = exprType((Node *) linitial(((NullIfExpr *) expr)->args));
 			break;
 		case T_NullTest:
 			type = BOOLOID;
@@ -1481,7 +1485,7 @@ exprTypmod(Node *expr)
 				CaseExpr   *cexpr = (CaseExpr *) expr;
 				Oid			casetype = cexpr->casetype;
 				int32		typmod;
-				List	   *arg;
+				ListCell   *arg;
 
 				if (!cexpr->defresult)
 					return -1;
@@ -1514,9 +1518,9 @@ exprTypmod(Node *expr)
 				CoalesceExpr *cexpr = (CoalesceExpr *) expr;
 				Oid			coalescetype = cexpr->coalescetype;
 				int32		typmod;
-				List	   *arg;
+				ListCell   *arg;
 
-				typmod = exprTypmod((Node *) lfirst(cexpr->args));
+				typmod = exprTypmod((Node *) linitial(cexpr->args));
 				foreach(arg, cexpr->args)
 				{
 					Node	   *e = (Node *) lfirst(arg);
@@ -1533,7 +1537,7 @@ exprTypmod(Node *expr)
 			{
 				NullIfExpr *nexpr = (NullIfExpr *) expr;
 
-				return exprTypmod((Node *) lfirst(nexpr->args));
+				return exprTypmod((Node *) linitial(nexpr->args));
 			}
 			break;
 		case T_CoerceToDomain:
@@ -1644,8 +1648,8 @@ make_row_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree)
 			   *rrow;
 	List	   *largs,
 			   *rargs;
-	List	   *largl,
-			   *rargl;
+	ListCell   *l,
+			   *r;
 	char	   *oprname;
 	BoolExprType boolop;
 
@@ -1690,15 +1694,12 @@ make_row_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree)
 		boolop = 0;			/* keep compiler quiet */
 	}
 
-	/* XXX use forboth */
-	rargl = rargs;
-	foreach(largl, largs)
+	forboth(l, largs, r, rargs)
 	{
-		Node	*larg = (Node *) lfirst(largl);
-		Node	*rarg = (Node *) lfirst(rargl);
+		Node	*larg = (Node *) lfirst(l);
+		Node	*rarg = (Node *) lfirst(r);
 		Node	*cmp;
 
-		rargl = lnext(rargl);
 		cmp = (Node *) make_op(pstate, opname, larg, rarg);
 		cmp = coerce_to_boolean(pstate, cmp, "row comparison");
 		if (result == NULL)
@@ -1732,8 +1733,8 @@ make_row_distinct_op(ParseState *pstate, List *opname,
 			   *rrow;
 	List	   *largs,
 			   *rargs;
-	List	   *largl,
-			   *rargl;
+	ListCell   *l,
+			   *r;
 
 	/* Inputs are untransformed RowExprs */
 	lrow = (RowExpr *) transformExpr(pstate, ltree);
@@ -1748,15 +1749,12 @@ make_row_distinct_op(ParseState *pstate, List *opname,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("unequal number of entries in row expression")));
 
-	/* XXX use forboth */
-	rargl = rargs;
-	foreach(largl, largs)
+	forboth(l, largs, r, rargs)
 	{
-		Node	*larg = (Node *) lfirst(largl);
-		Node	*rarg = (Node *) lfirst(rargl);
+		Node	*larg = (Node *) lfirst(l);
+		Node	*rarg = (Node *) lfirst(r);
 		Node	*cmp;
 
-		rargl = lnext(rargl);
 		cmp = (Node *) make_distinct_op(pstate, opname, larg, rarg);
 		if (result == NULL)
 			result = cmp;
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 64da3bb8425d752c9ac8164a39a4f4c86b9c94b1..2b48ef488d7712d58f9050c3357e01a10e31ab18 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.168 2004/04/02 21:30:44 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.169 2004/05/26 04:41:30 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -67,7 +67,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
 {
 	Oid			rettype;
 	Oid			funcid;
-	List	   *i;
+	ListCell   *l;
 	Node	   *first_arg = NULL;
 	int			nargs = length(fargs);
 	int			argn;
@@ -91,7 +91,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
 
 	if (fargs)
 	{
-		first_arg = lfirst(fargs);
+		first_arg = linitial(fargs);
 		Assert(first_arg != NULL);
 	}
 
@@ -108,7 +108,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
 		if (argtype == RECORDOID || ISCOMPLEX(argtype))
 		{
 			retval = ParseComplexProjection(pstate,
-											strVal(lfirst(funcname)),
+											strVal(linitial(funcname)),
 											first_arg);
 			if (retval)
 				return retval;
@@ -126,9 +126,9 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
 	MemSet(actual_arg_types, 0, FUNC_MAX_ARGS * sizeof(Oid));
 
 	argn = 0;
-	foreach(i, fargs)
+	foreach(l, fargs)
 	{
-		Node	   *arg = lfirst(i);
+		Node	   *arg = lfirst(l);
 
 		actual_arg_types[argn++] = exprType(arg);
 	}
@@ -149,8 +149,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
 		 * We can do it as a trivial coercion. coerce_type can handle
 		 * these cases, so why duplicate code...
 		 */
-		return coerce_type(pstate, lfirst(fargs), actual_arg_types[0],
-						   rettype,
+		return coerce_type(pstate, linitial(fargs),
+						   actual_arg_types[0], rettype,
 						   COERCION_EXPLICIT, COERCE_EXPLICIT_CALL);
 	}
 	else if (fdresult == FUNCDETAIL_NORMAL)
@@ -183,7 +183,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
 		{
 			Assert(nargs == 1);
 			Assert(length(funcname) == 1);
-			unknown_attribute(pstate, first_arg, strVal(lfirst(funcname)));
+			unknown_attribute(pstate, first_arg, strVal(linitial(funcname)));
 		}
 
 		/*
@@ -240,7 +240,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs,
 
 		aggref->aggfnoid = funcid;
 		aggref->aggtype = rettype;
-		aggref->target = lfirst(fargs);
+		aggref->target = linitial(fargs);
 		aggref->aggstar = agg_star;
 		aggref->aggdistinct = agg_distinct;
 
@@ -725,7 +725,7 @@ func_get_detail(List *funcname,
 				!ISCOMPLEX(targetType))
 			{
 				Oid			sourceType = argtypes[0];
-				Node	   *arg1 = lfirst(fargs);
+				Node	   *arg1 = linitial(fargs);
 
 				if ((sourceType == UNKNOWNOID && IsA(arg1, Const)) ||
 					(find_coercion_pathway(targetType, sourceType,
@@ -896,37 +896,51 @@ static int
 find_inheritors(Oid relid, Oid **supervec)
 {
 	Relation	inhrel;
-	HeapScanDesc inhscan;
-	ScanKeyData skey;
-	HeapTuple	inhtup;
-	Oid		   *relidvec;
 	int			nvisited;
 	List	   *visited,
 			   *queue;
-	List	   *elt;
-	bool		newrelid;
+	ListCell   *queue_item;
 
-	nvisited = 0;
-	queue = NIL;
+	/*
+	 * Begin the search at the relation itself, so add relid to the
+	 * queue.
+	 */
+	queue = list_make1_oid(relid);
 	visited = NIL;
 
 	inhrel = heap_openr(InheritsRelationName, AccessShareLock);
 
 	/*
-	 * Use queue to do a breadth-first traversal of the inheritance graph
-	 * 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 relids to check after this one, and visited is the list of
-	 * relids we need to output.
+	 * Use queue to do a breadth-first traversal of the inheritance
+	 * graph from the relid supplied up to the root.  Notice that we
+	 * append to the queue inside the loop --- this is okay because
+	 * the foreach() macro doesn't advance queue_item until the next
+	 * loop iteration begins.
 	 */
-	do
+	foreach(queue_item, queue)
 	{
-		/* find all types this relid inherits from, and add them to queue */
+		Oid				this_relid = lfirst_oid(queue_item);
+		ScanKeyData		skey;
+		HeapScanDesc	inhscan;
+		HeapTuple		inhtup;
+
+		/* If we've seen this relid already, skip it */
+		if (list_member_oid(visited, this_relid))
+			continue;
+
+		/*
+		 * Okay, this is a not-yet-seen relid. Add it to the list of
+		 * already-visited OIDs, then find all the types this relid
+		 * inherits from and add them to the queue. The one exception
+		 * is we don't add the original relation to 'visited'.
+		 */
+		if (queue_item != list_head(queue))
+			visited = lappend_oid(visited, this_relid);
 
 		ScanKeyInit(&skey,
 					Anum_pg_inherits_inhrelid,
 					BTEqualStrategyNumber, F_OIDEQ,
-					ObjectIdGetDatum(relid));
+					ObjectIdGetDatum(this_relid));
 
 		inhscan = heap_beginscan(inhrel, SnapshotNow, 1, &skey);
 
@@ -934,54 +948,34 @@ find_inheritors(Oid relid, Oid **supervec)
 		{
 			Form_pg_inherits inh = (Form_pg_inherits) GETSTRUCT(inhtup);
 
-			queue = lappendo(queue, inh->inhparent);
+			queue = lappend_oid(queue, inh->inhparent);
 		}
 
 		heap_endscan(inhscan);
-
-		/* pull next unvisited relid off the queue */
-
-		newrelid = false;
-		while (queue != NIL)
-		{
-			relid = lfirsto(queue);
-			queue = lnext(queue);
-			if (!oidMember(relid, visited))
-			{
-				newrelid = true;
-				break;
-			}
-		}
-
-		if (newrelid)
-		{
-			visited = lappendo(visited, relid);
-			nvisited++;
-		}
-	} while (newrelid);
+	}
 
 	heap_close(inhrel, AccessShareLock);
 
+	nvisited = list_length(visited);
 	if (nvisited > 0)
 	{
-		relidvec = (Oid *) palloc(nvisited * sizeof(Oid));
+		Oid		   *relidvec;
+		ListCell   *l;
+
+		relidvec = (Oid *) palloc(nvisited * sizeof(*relidvec));
 		*supervec = relidvec;
 
-		foreach(elt, visited)
+		foreach(l, visited)
 		{
 			/* return the type id, rather than the relation id */
-			*relidvec++ = get_rel_type_id(lfirsto(elt));
+			*relidvec++ = get_rel_type_id(lfirst_oid(l));
 		}
 	}
 	else
 		*supervec = 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.
-	 */
+	freeList(queue);
 
 	return nvisited;
 }
@@ -1117,7 +1111,7 @@ make_fn_arguments(ParseState *pstate,
 				  Oid *actual_arg_types,
 				  Oid *declared_arg_types)
 {
-	List	   *current_fargs;
+	ListCell   *current_fargs;
 	int			i = 0;
 
 	foreach(current_fargs, fargs)
@@ -1403,6 +1397,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
 	Oid			argoids[FUNC_MAX_ARGS];
 	int			argcount;
 	int			i;
+	ListCell   *args_item;
 
 	MemSet(argoids, 0, FUNC_MAX_ARGS * sizeof(Oid));
 	argcount = length(argtypes);
@@ -1412,9 +1407,10 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
 				 errmsg("functions cannot have more than %d arguments",
 						FUNC_MAX_ARGS)));
 
+	args_item = list_head(argtypes);
 	for (i = 0; i < argcount; i++)
 	{
-		TypeName   *t = (TypeName *) lfirst(argtypes);
+		TypeName   *t = (TypeName *) lfirst(args_item);
 
 		argoids[i] = LookupTypeName(t);
 
@@ -1424,7 +1420,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
 					 errmsg("type \"%s\" does not exist",
 							TypeNameToString(t))));
 
-		argtypes = lnext(argtypes);
+		args_item = lnext(args_item);
 	}
 
 	return LookupFuncName(funcname, argcount, argoids, noError);
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index 00b4c8e513eaa1282e767da0efc1fd78325dba65..c46c27481a549533478a02049626492841c74b2c 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.82 2003/11/29 19:51:52 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_node.c,v 1.83 2004/05/26 04:41:30 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -106,7 +106,7 @@ transformArraySubscripts(ParseState *pstate,
 	bool		isSlice = forceSlice;
 	List	   *upperIndexpr = NIL;
 	List	   *lowerIndexpr = NIL;
-	List	   *idx;
+	ListCell   *idx;
 	ArrayRef   *aref;
 
 	/* Get the type tuple for the array */
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index de4bf093ee950589320113bd8bd226b7c65af991..d7d50e187e3090f9e06700a45fc1b625c4774535 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.94 2004/04/18 18:12:58 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.95 2004/05/26 04:41:30 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -140,7 +140,7 @@ scanNameSpaceForRefname(ParseState *pstate, Node *nsnode,
 		return NULL;
 	if (IsA(nsnode, RangeTblRef))
 	{
-		int			varno = ((RangeTblRef *) nsnode)->rtindex;
+		int			   varno = ((RangeTblRef *) nsnode)->rtindex;
 		RangeTblEntry *rte = rt_fetch(varno, pstate->p_rtable);
 
 		if (strcmp(rte->eref->aliasname, refname) == 0)
@@ -174,7 +174,7 @@ scanNameSpaceForRefname(ParseState *pstate, Node *nsnode,
 	}
 	else if (IsA(nsnode, List))
 	{
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, (List *) nsnode)
 		{
@@ -249,7 +249,7 @@ scanNameSpaceForRelid(ParseState *pstate, Node *nsnode, Oid relid)
 	}
 	else if (IsA(nsnode, List))
 	{
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, (List *) nsnode)
 		{
@@ -321,7 +321,7 @@ checkNameSpaceConflicts(ParseState *pstate, Node *namespace1,
 	}
 	else if (IsA(namespace1, List))
 	{
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, (List *) namespace1)
 			checkNameSpaceConflicts(pstate, lfirst(l), namespace2);
@@ -378,7 +378,7 @@ scanNameSpaceForConflict(ParseState *pstate, Node *nsnode,
 	}
 	else if (IsA(nsnode, List))
 	{
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, (List *) nsnode)
 			scanNameSpaceForConflict(pstate, lfirst(l), rte1, aliasname1);
@@ -397,7 +397,7 @@ int
 RTERangeTablePosn(ParseState *pstate, RangeTblEntry *rte, int *sublevels_up)
 {
 	int			index;
-	List	   *temp;
+	ListCell   *l;
 
 	if (sublevels_up)
 		*sublevels_up = 0;
@@ -405,9 +405,9 @@ RTERangeTablePosn(ParseState *pstate, RangeTblEntry *rte, int *sublevels_up)
 	while (pstate != NULL)
 	{
 		index = 1;
-		foreach(temp, pstate->p_rtable)
+		foreach(l, pstate->p_rtable)
 		{
-			if (rte == (RangeTblEntry *) lfirst(temp))
+			if (rte == (RangeTblEntry *) lfirst(l))
 				return index;
 			index++;
 		}
@@ -460,7 +460,7 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, char *colname)
 {
 	Node	   *result = NULL;
 	int			attnum = 0;
-	List	   *c;
+	ListCell   *c;
 
 	/*
 	 * Scan the user column names (or aliases) for a match. Complain if
@@ -546,7 +546,7 @@ colNameToVar(ParseState *pstate, char *colname, bool localonly)
 
 	while (pstate != NULL)
 	{
-		List	   *ns;
+		ListCell   *ns;
 
 		/*
 		 * We need to look only at top-level namespace items, and even for
@@ -841,7 +841,7 @@ addRangeTableEntryForSubquery(ParseState *pstate,
 	Alias	   *eref;
 	int			numaliases;
 	int			varattno;
-	List	   *tlistitem;
+	ListCell   *tlistitem;
 
 	rte->rtekind = RTE_SUBQUERY;
 	rte->relid = InvalidOid;
@@ -1027,7 +1027,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
 	}
 	else if (functyptype == 'p' && funcrettype == RECORDOID)
 	{
-		List	   *col;
+		ListCell   *col;
 
 		/* Use the column definition list to form the alias list */
 		eref->colnames = NIL;
@@ -1101,11 +1101,8 @@ addRangeTableEntryForJoin(ParseState *pstate,
 
 	/* fill in any unspecified alias columns */
 	if (numaliases < length(colnames))
-	{
-		while (numaliases-- > 0)
-			colnames = lnext(colnames);
-		eref->colnames = nconc(eref->colnames, colnames);
-	}
+		eref->colnames = nconc(eref->colnames,
+							   list_copy_tail(colnames, numaliases));
 
 	rte->eref = eref;
 
@@ -1145,7 +1142,7 @@ isForUpdate(ParseState *pstate, char *refname)
 	{
 		if (pstate->p_forUpdate != NIL)
 		{
-			if (lfirst(pstate->p_forUpdate) == NULL)
+			if (linitial(pstate->p_forUpdate) == NULL)
 			{
 				/* all tables used in query */
 				return true;
@@ -1153,7 +1150,7 @@ isForUpdate(ParseState *pstate, char *refname)
 			else
 			{
 				/* just the named tables */
-				List	   *l;
+				ListCell   *l;
 
 				foreach(l, pstate->p_forUpdate)
 				{
@@ -1282,8 +1279,8 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
 		case RTE_SUBQUERY:
 			{
 				/* Subquery RTE */
-				List	   *aliasp = rte->eref->colnames;
-				List	   *tlistitem;
+				ListCell	   *aliasp_item = list_head(rte->eref->colnames);
+				ListCell	   *tlistitem;
 
 				varattno = 0;
 				foreach(tlistitem, rte->subquery->targetList)
@@ -1298,10 +1295,10 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
 					if (colnames)
 					{
 						/* Assume there is one alias per target item */
-						char	   *label = strVal(lfirst(aliasp));
+						char	   *label = strVal(lfirst(aliasp_item));
 
 						*colnames = lappend(*colnames, makeString(pstrdup(label)));
-						aliasp = lnext(aliasp);
+						aliasp_item = lnext(aliasp_item);
 					}
 
 					if (colvars)
@@ -1385,7 +1382,7 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
 					 */
 					if (colnames)
 						*colnames = lappend(*colnames,
-											lfirst(rte->eref->colnames));
+											linitial(rte->eref->colnames));
 
 					if (colvars)
 					{
@@ -1400,7 +1397,7 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
 				}
 				else if (functyptype == 'p' && funcrettype == RECORDOID)
 				{
-					List	   *col;
+					ListCell   *col;
 					int			attnum = 0;
 
 					foreach(col, coldeflist)
@@ -1442,39 +1439,36 @@ expandRTE(ParseState *pstate, RangeTblEntry *rte,
 		case RTE_JOIN:
 			{
 				/* Join RTE */
-				List	   *aliasp = rte->eref->colnames;
-				List	   *aliasvars = rte->joinaliasvars;
+				ListCell	*colname;
+				ListCell	*aliasvar;
+
+				Assert(length(rte->eref->colnames) == length(rte->joinaliasvars));
 
 				varattno = 0;
-				while (aliasp)
+				forboth (colname, rte->eref->colnames, aliasvar, rte->joinaliasvars)
 				{
-					Assert(aliasvars);
 					varattno++;
 
 					if (colnames)
 					{
-						char	   *label = strVal(lfirst(aliasp));
+						char	   *label = strVal(lfirst(colname));
 
 						*colnames = lappend(*colnames, makeString(pstrdup(label)));
 					}
 
 					if (colvars)
 					{
-						Node	   *aliasvar = (Node *) lfirst(aliasvars);
+						Node	   *avar = (Node *) lfirst(aliasvar);
 						Var		   *varnode;
 
 						varnode = makeVar(rtindex, varattno,
-										  exprType(aliasvar),
-										  exprTypmod(aliasvar),
+										  exprType(avar),
+										  exprTypmod(avar),
 										  sublevels_up);
 
 						*colvars = lappend(*colvars, varnode);
 					}
-
-					aliasp = lnext(aliasp);
-					aliasvars = lnext(aliasvars);
 				}
-				Assert(aliasvars == NIL);
 			}
 			break;
 		default:
@@ -1492,14 +1486,16 @@ expandRelAttrs(ParseState *pstate, RangeTblEntry *rte)
 {
 	List	   *names,
 			   *vars;
+	ListCell   *name,
+			   *var;
 	List	   *te_list = NIL;
 
 	expandRTE(pstate, rte, &names, &vars);
 
-	while (names)
+	forboth (name, names, var, vars)
 	{
-		char	   *label = strVal(lfirst(names));
-		Node	   *varnode = (Node *) lfirst(vars);
+		char	   *label = strVal(lfirst(name));
+		Node	   *varnode = (Node *) lfirst(var);
 		TargetEntry *te = makeNode(TargetEntry);
 
 		te->resdom = makeResdom((AttrNumber) pstate->p_next_resno++,
@@ -1509,12 +1505,9 @@ expandRelAttrs(ParseState *pstate, RangeTblEntry *rte)
 								false);
 		te->expr = (Expr *) varnode;
 		te_list = lappend(te_list, te);
-
-		names = lnext(names);
-		vars = lnext(vars);
 	}
 
-	Assert(vars == NIL);		/* lists not same length? */
+	Assert(name == NULL && var == NULL); /* lists not the same length? */
 
 	return te_list;
 }
@@ -1790,11 +1783,11 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
 TargetEntry *
 get_tle_by_resno(List *tlist, AttrNumber resno)
 {
-	List	   *i;
+	ListCell  *l;
 
-	foreach(i, tlist)
+	foreach(l, tlist)
 	{
-		TargetEntry *tle = (TargetEntry *) lfirst(i);
+		TargetEntry *tle = (TargetEntry *) lfirst(l);
 
 		if (tle->resdom->resno == resno)
 			return tle;
@@ -1917,7 +1910,7 @@ static void
 warnAutoRange(ParseState *pstate, RangeVar *relation)
 {
 	bool		foundInFromCl = false;
-	List	   *temp;
+	ListCell   *temp;
 
 	if (!add_missing_from)
 	{
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index fbee22b37d3b2ef67b9c7bc5d11561580998a401..9eaf9eb53a952ef9da65eeda82bac269cdbfe160 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.117 2004/05/10 22:44:46 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.118 2004/05/26 04:41:30 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -93,7 +93,7 @@ List *
 transformTargetList(ParseState *pstate, List *targetlist)
 {
 	FastList	p_target;
-	List	   *o_target;
+	ListCell   *o_target;
 
 	FastListInit(&p_target);
 
@@ -134,15 +134,15 @@ transformTargetList(ParseState *pstate, List *targetlist)
 					{
 						case 2:
 							schemaname = NULL;
-							relname = strVal(lfirst(fields));
+							relname = strVal(linitial(fields));
 							break;
 						case 3:
-							schemaname = strVal(lfirst(fields));
+							schemaname = strVal(linitial(fields));
 							relname = strVal(lsecond(fields));
 							break;
 						case 4:
 						{
-							char	   *name1 = strVal(lfirst(fields));
+							char	   *name1 = strVal(linitial(fields));
 
 							/*
 							 * We check the catalog name and then ignore
@@ -215,7 +215,7 @@ transformTargetList(ParseState *pstate, List *targetlist)
 void
 markTargetListOrigins(ParseState *pstate, List *targetlist)
 {
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, targetlist)
 	{
@@ -468,7 +468,7 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
 		/*
 		 * Do initial validation of user-supplied INSERT column list.
 		 */
-		List	   *tl;
+		ListCell   *tl;
 
 		foreach(tl, cols)
 		{
@@ -502,7 +502,7 @@ ExpandAllTables(ParseState *pstate)
 {
 	List	   *target = NIL;
 	bool		found_table = false;
-	List	   *ns;
+	ListCell   *ns;
 
 	foreach(ns, pstate->p_namespace)
 	{
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index e6e8b00cda492a5601c8d0ef1865d3c70484db92..473d52399e3b136001ac4d663e16682bc39725e3 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.65 2004/03/21 22:29:11 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_type.c,v 1.66 2004/05/26 04:41:30 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -63,16 +63,16 @@ LookupTypeName(const TypeName *typename)
 								NameListToString(typename->names))));
 				break;
 			case 2:
-				rel->relname = strVal(lfirst(typename->names));
+				rel->relname = strVal(linitial(typename->names));
 				field = strVal(lsecond(typename->names));
 				break;
 			case 3:
-				rel->schemaname = strVal(lfirst(typename->names));
+				rel->schemaname = strVal(linitial(typename->names));
 				rel->relname = strVal(lsecond(typename->names));
 				field = strVal(lthird(typename->names));
 				break;
 			case 4:
-				rel->catalogname = strVal(lfirst(typename->names));
+				rel->catalogname = strVal(linitial(typename->names));
 				rel->schemaname = strVal(lsecond(typename->names));
 				rel->relname = strVal(lthird(typename->names));
 				field = strVal(lfourth(typename->names));
@@ -155,11 +155,11 @@ TypeNameToString(const TypeName *typename)
 	if (typename->names != NIL)
 	{
 		/* Emit possibly-qualified name as-is */
-		List	   *l;
+		ListCell   *l;
 
 		foreach(l, typename->names)
 		{
-			if (l != typename->names)
+			if (l != list_head(typename->names))
 				appendStringInfoChar(&string, '.');
 			appendStringInfoString(&string, strVal(lfirst(l)));
 		}
@@ -488,7 +488,7 @@ parseTypeString(const char *str, Oid *type_id, int32 *typmod)
 	 */
 	if (length(raw_parsetree_list) != 1)
 		goto fail;
-	stmt = (SelectStmt *) lfirst(raw_parsetree_list);
+	stmt = (SelectStmt *) linitial(raw_parsetree_list);
 	if (stmt == NULL ||
 		!IsA(stmt, SelectStmt) ||
 		stmt->distinctClause != NIL ||
@@ -505,7 +505,7 @@ parseTypeString(const char *str, Oid *type_id, int32 *typmod)
 		goto fail;
 	if (length(stmt->targetList) != 1)
 		goto fail;
-	restarget = (ResTarget *) lfirst(stmt->targetList);
+	restarget = (ResTarget *) linitial(stmt->targetList);
 	if (restarget == NULL ||
 		!IsA(restarget, ResTarget) ||
 		restarget->name != NULL ||
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 1cd340f978a02007881acbe3a0f20e14059d7462..685eebc577fba814dacf94531da37e28039bdc0c 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.94 2004/05/18 22:49:51 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.95 2004/05/26 04:41:33 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -167,7 +167,7 @@ InsertRule(char *rulname,
 	if (event_qual != NULL)
 	{
 		/* Find query containing OLD/NEW rtable entries */
-		Query	   *qry = (Query *) lfirst(action);
+		Query	   *qry = (Query *) linitial(action);
 
 		qry = getInsertSelectQuery(qry, NULL);
 		recordDependencyOnExpr(&myself, event_qual, qry->rtable,
@@ -193,7 +193,7 @@ DefineQueryRewrite(RuleStmt *stmt)
 	Oid			ruleId;
 	int			event_attno;
 	Oid			event_attype;
-	List	   *l;
+	ListCell   *l;
 	Query	   *query;
 	AclResult	aclresult;
 	bool		RelisBecomingView = false;
@@ -245,7 +245,7 @@ DefineQueryRewrite(RuleStmt *stmt)
 	 */
 	if (event_type == CMD_SELECT)
 	{
-		List	   *tllist;
+		ListCell	   *tllist;
 		int			i;
 
 		/*
@@ -268,7 +268,7 @@ DefineQueryRewrite(RuleStmt *stmt)
 		/*
 		 * ... the one action must be a SELECT, ...
 		 */
-		query = (Query *) lfirst(action);
+		query = (Query *) linitial(action);
 		if (!is_instead || query->commandType != CMD_SELECT)
 			ereport(ERROR,
 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -509,7 +509,7 @@ DefineQueryRewrite(RuleStmt *stmt)
 static void
 setRuleCheckAsUser_Query(Query *qry, AclId userid)
 {
-	List	   *l;
+	ListCell   *l;
 
 	/* Set all the RTEs in this query node */
 	foreach(l, qry->rtable)
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 3b898b973d8ec9eb52f5c7faded630ee84af7495..9ac665449ce2647d3e95b6aa376512df4103babb 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.135 2004/05/10 22:44:46 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.136 2004/05/26 04:41:33 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -238,13 +238,13 @@ static List *
 adjustJoinTreeList(Query *parsetree, bool removert, int rt_index)
 {
 	List	   *newjointree = copyObject(parsetree->jointree->fromlist);
-	List	   *jjt;
+	ListCell   *l;
 
 	if (removert)
 	{
-		foreach(jjt, newjointree)
+		foreach(l, newjointree)
 		{
-			RangeTblRef *rtr = lfirst(jjt);
+			RangeTblRef *rtr = lfirst(l);
 
 			if (IsA(rtr, RangeTblRef) &&
 				rtr->rtindex == rt_index)
@@ -295,7 +295,7 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
 	List	   *new_tlist = NIL;
 	int			attrno,
 				numattrs;
-	List	   *temp;
+	ListCell   *temp;
 
 	/*
 	 * Scan the tuple description in the relation's relcache entry to make
@@ -627,7 +627,7 @@ ApplyRetrieveRule(Query *parsetree,
 	 * Make a modifiable copy of the view query, and recursively expand
 	 * any view references inside it.
 	 */
-	rule_action = copyObject(lfirst(rule->actions));
+	rule_action = copyObject(linitial(rule->actions));
 
 	rule_action = fireRIRrules(rule_action, activeRIRs);
 
@@ -687,7 +687,7 @@ static void
 markQueryForUpdate(Query *qry, bool skipOldNew)
 {
 	Index		rti = 0;
-	List	   *l;
+	ListCell   *l;
 
 	foreach(l, qry->rtable)
 	{
@@ -865,7 +865,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs)
 		if (locks != NIL)
 		{
 			List	   *newActiveRIRs;
-			List	   *l;
+			ListCell   *l;
 
 			if (oidMember(RelationGetRelid(rel), activeRIRs))
 				ereport(ERROR,
@@ -995,15 +995,15 @@ fireRules(Query *parsetree,
 		  Query **qual_product)
 {
 	List	   *results = NIL;
-	List	   *i;
+	ListCell   *l;
 
-	foreach(i, locks)
+	foreach(l, locks)
 	{
-		RewriteRule *rule_lock = (RewriteRule *) lfirst(i);
+		RewriteRule *rule_lock = (RewriteRule *) lfirst(l);
 		Node	   *event_qual = rule_lock->qual;
 		List	   *actions = rule_lock->actions;
 		QuerySource qsrc;
-		List	   *r;
+		ListCell   *r;
 
 		/* Determine correct QuerySource value for actions */
 		if (rule_lock->isInstead)
@@ -1143,8 +1143,8 @@ RewriteQuery(Query *parsetree, List *rewrite_events)
 			 */
 			if (product_queries != NIL)
 			{
-				List	   *n;
-				rewrite_event *rev;
+				ListCell	   *n;
+				rewrite_event  *rev;
 
 				foreach(n, rewrite_events)
 				{
@@ -1225,7 +1225,7 @@ QueryRewrite(Query *parsetree)
 {
 	List	   *querylist;
 	List	   *results = NIL;
-	List	   *l;
+	ListCell   *l;
 	CmdType		origCmdType;
 	bool		foundOriginalQuery;
 	Query	   *lastInstead;
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index 45b60715966e8e9931dc121fc407d4c20a38da55..4079230c0b128aceeb141cbd9e022bfee99223a1 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.82 2004/05/10 22:44:46 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.83 2004/05/26 04:41:33 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -216,7 +216,6 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up)
 	if (node && IsA(node, Query))
 	{
 		Query	   *qry = (Query *) node;
-		List	   *l;
 
 		/*
 		 * If we are starting at a Query, and sublevels_up is zero, then
@@ -227,6 +226,8 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up)
 		 */
 		if (sublevels_up == 0)
 		{
+			ListCell   *l;
+
 			if (qry->resultRelation)
 				qry->resultRelation += offset;
 			foreach(l, qry->rowMarks)
@@ -356,7 +357,6 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
 	if (node && IsA(node, Query))
 	{
 		Query	   *qry = (Query *) node;
-		List	   *l;
 
 		/*
 		 * If we are starting at a Query, and sublevels_up is zero, then
@@ -367,6 +367,8 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
 		 */
 		if (sublevels_up == 0)
 		{
+			ListCell   *l;
+
 			if (qry->resultRelation == rt_index)
 				qry->resultRelation = new_index;
 			foreach(l, qry->rowMarks)
@@ -678,7 +680,7 @@ getInsertSelectQuery(Query *parsetree, Query ***subquery_ptr)
 	Assert(parsetree->jointree && IsA(parsetree->jointree, FromExpr));
 	if (length(parsetree->jointree->fromlist) != 1)
 		elog(ERROR, "expected to find SELECT subquery");
-	rtr = (RangeTblRef *) lfirst(parsetree->jointree->fromlist);
+	rtr = (RangeTblRef *) linitial(parsetree->jointree->fromlist);
 	Assert(IsA(rtr, RangeTblRef));
 	selectrte = rt_fetch(rtr->rtindex, parsetree->rtable);
 	selectquery = selectrte->subquery;
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 604dd9819eba0d12d6ade21e107af1417f9f220d..7a4390538b66c1bb80d877a7cae02837c3965dab 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.414 2004/05/23 03:50:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.415 2004/05/26 04:41:35 neilc Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -428,7 +428,7 @@ pg_parse_and_rewrite(const char *query_string,	/* string to execute */
 {
 	List	   *raw_parsetree_list;
 	List	   *querytree_list;
-	List	   *list_item;
+	ListCell   *list_item;
 
 	/*
 	 * (1) parse the request string into a list of raw parse trees.
@@ -443,7 +443,7 @@ pg_parse_and_rewrite(const char *query_string,	/* string to execute */
 	{
 		Node	   *parsetree = (Node *) lfirst(list_item);
 
-		querytree_list = nconc(querytree_list,
+		querytree_list = list_concat(querytree_list,
 							   pg_analyze_and_rewrite(parsetree,
 													  paramTypes,
 													  numParams));
@@ -468,8 +468,8 @@ pg_parse_and_rewrite(const char *query_string,	/* string to execute */
 List *
 pg_parse_query(const char *query_string)
 {
-	List	   *raw_parsetree_list,
-			   *parsetree_item;
+	List	   *raw_parsetree_list;
+	ListCell   *parsetree_item;
 
 	if (log_statement == LOGSTMT_ALL)
 		ereport(LOG,
@@ -571,7 +571,7 @@ List *
 pg_rewrite_queries(List *querytree_list)
 {
 	List	   *new_list = NIL;
-	List	   *list_item;
+	ListCell   *list_item;
 
 	if (log_parser_stats)
 		ResetUsage();
@@ -598,7 +598,7 @@ pg_rewrite_queries(List *querytree_list)
 			/* rewrite regular queries */
 			List	   *rewritten = QueryRewrite(querytree);
 
-			new_list = nconc(new_list, rewritten);
+			new_list = list_concat(new_list, rewritten);
 		}
 	}
 
@@ -691,7 +691,7 @@ List *
 pg_plan_queries(List *querytrees, bool needSnapshot)
 {
 	List	   *plan_list = NIL;
-	List	   *query_list;
+	ListCell   *query_list;
 
 	foreach(query_list, querytrees)
 	{
@@ -730,8 +730,8 @@ exec_simple_query(const char *query_string)
 {
 	CommandDest dest = whereToSendOutput;
 	MemoryContext oldcontext;
-	List	   *parsetree_list,
-			   *parsetree_item;
+	List	   *parsetree_list;
+	ListCell   *parsetree_item;
 	struct timeval start_t,
 				stop_t;
 	bool		save_log_duration = log_duration;
@@ -946,7 +946,7 @@ exec_simple_query(const char *query_string)
 			 */
 			finish_xact_command();
 		}
-		else if (lnext(parsetree_item) == NIL)
+		else if (lnext(parsetree_item) == NULL)
 		{
 			/*
 			 * If this is the last parsetree of the query string, close
@@ -1129,14 +1129,14 @@ exec_parse_message(const char *query_string,	/* string to execute */
 	 * is mainly to keep the protocol simple --- otherwise we'd need to
 	 * worry about multiple result tupdescs and things like that.
 	 */
-	if (length(parsetree_list) > 1)
+	if (list_length(parsetree_list) > 1)
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("cannot insert multiple commands into a prepared statement")));
 
 	if (parsetree_list != NIL)
 	{
-		Node	   *parsetree = (Node *) lfirst(parsetree_list);
+		Node	   *parsetree = (Node *) linitial(parsetree_list);
 		int			i;
 
 		/*
@@ -1198,7 +1198,7 @@ exec_parse_message(const char *query_string,	/* string to execute */
 						(errcode(ERRCODE_INDETERMINATE_DATATYPE),
 				  errmsg("could not determine data type of parameter $%d",
 						 i + 1)));
-			param_list = lappendo(param_list, ptype);
+			param_list = lappend_oid(param_list, ptype);
 		}
 
 		if (log_parser_stats)
@@ -1342,11 +1342,11 @@ exec_bind_message(StringInfo input_message)
 				   errmsg("unnamed prepared statement does not exist")));
 	}
 
-	if (numParams != length(pstmt->argtype_list))
+	if (numParams != list_length(pstmt->argtype_list))
 		ereport(ERROR,
 				(errcode(ERRCODE_PROTOCOL_VIOLATION),
 				 errmsg("bind message supplies %d parameters, but prepared statement \"%s\" requires %d",
-					numParams, stmt_name, length(pstmt->argtype_list))));
+					numParams, stmt_name, list_length(pstmt->argtype_list))));
 
 	/*
 	 * Create the portal.  Allow silent replacement of an existing portal
@@ -1374,7 +1374,7 @@ exec_bind_message(StringInfo input_message)
 	if (numParams > 0)
 	{
 		bool		isaborted = IsAbortedTransactionBlockState();
-		List	   *l;
+		ListCell   *l;
 		MemoryContext oldContext;
 
 		oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
@@ -1385,7 +1385,7 @@ exec_bind_message(StringInfo input_message)
 		i = 0;
 		foreach(l, pstmt->argtype_list)
 		{
-			Oid			ptype = lfirsto(l);
+			Oid			ptype = lfirst_oid(l);
 			int32		plength;
 			bool		isNull;
 
@@ -1587,9 +1587,9 @@ exec_execute_message(const char *portal_name, long max_rows)
 	BeginCommand(portal->commandTag, dest);
 
 	/* Check for transaction-control commands */
-	if (length(portal->parseTrees) == 1)
+	if (list_length(portal->parseTrees) == 1)
 	{
-		Query	   *query = (Query *) lfirst(portal->parseTrees);
+		Query	   *query = (Query *) linitial(portal->parseTrees);
 
 		if (query->commandType == CMD_UTILITY &&
 			query->utilityStmt != NULL &&
@@ -1690,7 +1690,7 @@ exec_describe_statement_message(const char *stmt_name)
 {
 	PreparedStatement *pstmt;
 	TupleDesc	tupdesc;
-	List	   *l;
+	ListCell   *l;
 	StringInfoData buf;
 
 	/* Find prepared statement */
@@ -1713,11 +1713,11 @@ exec_describe_statement_message(const char *stmt_name)
 	 * First describe the parameters...
 	 */
 	pq_beginmessage(&buf, 't'); /* parameter description message type */
-	pq_sendint(&buf, length(pstmt->argtype_list), 2);
+	pq_sendint(&buf, list_length(pstmt->argtype_list), 2);
 
 	foreach(l, pstmt->argtype_list)
 	{
-		Oid			ptype = lfirsto(l);
+		Oid			ptype = lfirst_oid(l);
 
 		pq_sendint(&buf, (int) ptype, 4);
 	}
@@ -1732,7 +1732,7 @@ exec_describe_statement_message(const char *stmt_name)
 		List	   *targetlist;
 
 		if (ChoosePortalStrategy(pstmt->query_list) == PORTAL_ONE_SELECT)
-			targetlist = ((Query *) lfirst(pstmt->query_list))->targetList;
+			targetlist = ((Query *) linitial(pstmt->query_list))->targetList;
 		else
 			targetlist = NIL;
 		SendRowDescriptionMessage(tupdesc, targetlist, NULL);
@@ -1766,7 +1766,7 @@ exec_describe_portal_message(const char *portal_name)
 		List	   *targetlist;
 
 		if (portal->strategy == PORTAL_ONE_SELECT)
-			targetlist = ((Query *) lfirst(portal->parseTrees))->targetList;
+			targetlist = ((Query *) linitial(portal->parseTrees))->targetList;
 		else
 			targetlist = NIL;
 		SendRowDescriptionMessage(portal->tupDesc, targetlist,
@@ -2524,17 +2524,19 @@ PostgresMain(int argc, char *argv[], const char *username)
 	 */
 	if (MyProcPort != NULL)
 	{
-		List	   *gucopts = MyProcPort->guc_options;
+		ListCell   *gucopts = list_head(MyProcPort->guc_options);
 
 		while (gucopts)
 		{
-			char	   *name,
-					   *value;
+			char *name;
+			char *value;
 
 			name = lfirst(gucopts);
 			gucopts = lnext(gucopts);
+
 			value = lfirst(gucopts);
 			gucopts = lnext(gucopts);
+
 			SetConfigOption(name, value, PGC_BACKEND, PGC_S_CLIENT);
 		}
 
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index c213182ad1f34891e29afcd33655bf8fd180988b..2608588234cc88bdf686c3f35bcdb03096341243 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -8,10 +8,11 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.77 2004/03/21 22:29:11 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.78 2004/05/26 04:41:35 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
+
 #include "postgres.h"
 
 #include "executor/executor.h"
@@ -200,9 +201,9 @@ ChoosePortalStrategy(List *parseTrees)
 
 	strategy = PORTAL_MULTI_QUERY;		/* default assumption */
 
-	if (length(parseTrees) == 1)
+	if (list_length(parseTrees) == 1)
 	{
-		Query	   *query = (Query *) lfirst(parseTrees);
+		Query	   *query = (Query *) linitial(parseTrees);
 
 		if (query->commandType == CMD_SELECT &&
 			query->canSetTag &&
@@ -267,8 +268,8 @@ PortalStart(Portal portal, ParamListInfo params)
 			 * Create QueryDesc in portal's context; for the moment, set
 			 * the destination to None.
 			 */
-			queryDesc = CreateQueryDesc((Query *) lfirst(portal->parseTrees),
-									  (Plan *) lfirst(portal->planTrees),
+			queryDesc = CreateQueryDesc((Query *) linitial(portal->parseTrees),
+										(Plan *) linitial(portal->planTrees),
 										None_Receiver,
 										params,
 										false);
@@ -304,7 +305,7 @@ PortalStart(Portal portal, ParamListInfo params)
 			 * will take care of it.
 			 */
 			portal->tupDesc =
-				UtilityTupleDescriptor(((Query *) lfirst(portal->parseTrees))->utilityStmt);
+				UtilityTupleDescriptor(((Query *) linitial(portal->parseTrees))->utilityStmt);
 
 			/*
 			 * Reset cursor position data to "start of query"
@@ -473,7 +474,7 @@ PortalRun(Portal portal, long count,
 
 				PortalCreateHoldStore(portal);
 				treceiver = CreateDestReceiver(Tuplestore, portal);
-				PortalRunUtility(portal, lfirst(portal->parseTrees),
+				PortalRunUtility(portal, linitial(portal->parseTrees),
 								 treceiver, NULL);
 				(*treceiver->rDestroy) (treceiver);
 				portal->portalUtilReady = true;
@@ -800,8 +801,8 @@ PortalRunMulti(Portal portal,
 			   DestReceiver *dest, DestReceiver *altdest,
 			   char *completionTag)
 {
-	List	   *plantree_list = portal->planTrees;
-	List	   *querylist_item;
+	ListCell   *planlist_item = list_head(portal->planTrees);
+	ListCell   *querylist_item;
 
 	/*
 	 * If the destination is RemoteExecute, change to None.  The reason is
@@ -825,9 +826,9 @@ PortalRunMulti(Portal portal,
 	foreach(querylist_item, portal->parseTrees)
 	{
 		Query	   *query = (Query *) lfirst(querylist_item);
-		Plan	   *plan = (Plan *) lfirst(plantree_list);
+		Plan	   *plan = (Plan *) lfirst(planlist_item);
 
-		plantree_list = lnext(plantree_list);
+		planlist_item = lnext(planlist_item);
 
 		/*
 		 * If we got a cancel signal in prior command, quit
@@ -885,7 +886,7 @@ PortalRunMulti(Portal portal,
 		 * Increment command counter between queries, but not after the
 		 * last one.
 		 */
-		if (plantree_list != NIL)
+		if (planlist_item != NULL)
 			CommandCounterIncrement();
 
 		/*
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index bcf071ea8a0635bbd5a11aa3328a6d8d4846e9af..fd9427c203d4f415978eb32f848625afe2452239 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.215 2004/05/07 19:12:26 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.216 2004/05/26 04:41:35 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -331,7 +331,7 @@ ProcessUtility(Node *parsetree,
 
 							if (stmt->options)
 							{
-								List	   *head;
+								ListCell   *head;
 
 								foreach(head, stmt->options)
 								{
@@ -339,10 +339,10 @@ ProcessUtility(Node *parsetree,
 
 									if (strcmp(item->defname, "transaction_isolation") == 0)
 										SetPGVariable("transaction_isolation",
-											makeList1(item->arg), false);
+											list_make1(item->arg), false);
 									else if (strcmp(item->defname, "transaction_read_only") == 0)
 										SetPGVariable("transaction_read_only",
-											makeList1(item->arg), false);
+											list_make1(item->arg), false);
 								}
 							}
 						}
@@ -405,7 +405,7 @@ ProcessUtility(Node *parsetree,
 		case T_DropStmt:
 			{
 				DropStmt   *stmt = (DropStmt *) parsetree;
-				List	   *arg;
+				ListCell   *arg;
 
 				foreach(arg, stmt->objects)
 				{
@@ -743,7 +743,7 @@ ProcessUtility(Node *parsetree,
 				 */
 				if (strcmp(n->name, "TRANSACTION") == 0)
 				{
-					List	   *head;
+					ListCell   *head;
 
 					foreach(head, n->args)
 					{
@@ -751,15 +751,15 @@ ProcessUtility(Node *parsetree,
 
 						if (strcmp(item->defname, "transaction_isolation") == 0)
 							SetPGVariable("transaction_isolation",
-									  makeList1(item->arg), n->is_local);
+									  list_make1(item->arg), n->is_local);
 						else if (strcmp(item->defname, "transaction_read_only") == 0)
 							SetPGVariable("transaction_read_only",
-									  makeList1(item->arg), n->is_local);
+									  list_make1(item->arg), n->is_local);
 					}
 				}
 				else if (strcmp(n->name, "SESSION CHARACTERISTICS") == 0)
 				{
-					List	   *head;
+					ListCell   *head;
 
 					foreach(head, n->args)
 					{
@@ -767,10 +767,10 @@ ProcessUtility(Node *parsetree,
 
 						if (strcmp(item->defname, "transaction_isolation") == 0)
 							SetPGVariable("default_transaction_isolation",
-									  makeList1(item->arg), n->is_local);
+									  list_make1(item->arg), n->is_local);
 						else if (strcmp(item->defname, "transaction_read_only") == 0)
 							SetPGVariable("default_transaction_read_only",
-									  makeList1(item->arg), n->is_local);
+									  list_make1(item->arg), n->is_local);
 					}
 				}
 				else
diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c
index 0bd8658b9f32132d6d1be0f669848bd0cf20d633..bb34667c4d3c972d51e6c7adb736a7cbec7f2ec1 100644
--- a/src/backend/utils/adt/name.c
+++ b/src/backend/utils/adt/name.c
@@ -14,7 +14,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/name.c,v 1.50 2003/11/29 19:51:59 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/name.c,v 1.51 2004/05/26 04:41:37 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -342,7 +342,8 @@ current_schema(PG_FUNCTION_ARGS)
 
 	if (search_path == NIL)
 		PG_RETURN_NULL();
-	nspname = get_namespace_name(lfirsto(search_path));
+	nspname = get_namespace_name(linitial_oid(search_path));
+	list_free(search_path);
 	if (!nspname)
 		PG_RETURN_NULL();		/* recently-deleted namespace? */
 	PG_RETURN_DATUM(DirectFunctionCall1(namein, CStringGetDatum(nspname)));
@@ -352,25 +353,27 @@ Datum
 current_schemas(PG_FUNCTION_ARGS)
 {
 	List	   *search_path = fetch_search_path(PG_GETARG_BOOL(0));
+	ListCell   *l;
 	Datum	   *names;
 	int			i;
 	ArrayType  *array;
 
 	/* +1 here is just to avoid palloc(0) error */
+
 	names = (Datum *) palloc((length(search_path) + 1) * sizeof(Datum));
 	i = 0;
-	while (search_path)
+	foreach(l, search_path)
 	{
 		char	   *nspname;
 
-		nspname = get_namespace_name(lfirsto(search_path));
+		nspname = get_namespace_name(lfirst_oid(l));
 		if (nspname)			/* watch out for deleted namespace */
 		{
 			names[i] = DirectFunctionCall1(namein, CStringGetDatum(nspname));
 			i++;
 		}
-		search_path = lnext(search_path);
 	}
+	list_free(search_path);
 
 	array = construct_array(names, i,
 							NAMEOID,
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index fe2e7aa6cf86095f9d113c3c692a07ed216466de..9c688401ece6d3a92359cd939f37099fe18a655c 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.87 2004/05/07 00:24:58 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.88 2004/05/26 04:41:37 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1099,7 +1099,7 @@ stringToQualifiedNameList(const char *string, const char *caller)
 	char	   *rawname;
 	List	   *result = NIL;
 	List	   *namelist;
-	List	   *l;
+	ListCell   *l;
 
 	/* We need a modifiable copy of the input string. */
 	rawname = pstrdup(string);
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 47384fbb89fd1286601d0c1f67f5a44ecf3952a0..9e3a06cd822329517ec6b8a63918c0191d788977 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -17,7 +17,7 @@
  *
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.67 2004/02/03 17:34:03 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.68 2004/05/26 04:41:38 neilc Exp $
  *
  * ----------
  */
@@ -2571,8 +2571,8 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
 	char		attname[MAX_QUOTED_NAME_LEN];
 	char		fkattname[MAX_QUOTED_NAME_LEN];
 	const char *sep;
-	List		*list;
-	List		*list2;
+	ListCell	*l;
+	ListCell	*l2;
 	int			old_work_mem;
 	char		workmembuf[32];
 	int			spi_result;
@@ -2605,9 +2605,9 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
 
 	sprintf(querystr, "SELECT ");
 	sep="";
-	foreach(list, fkconstraint->fk_attrs)
+	foreach(l, fkconstraint->fk_attrs)
 	{
-		quoteOneName(attname, strVal(lfirst(list)));
+		quoteOneName(attname, strVal(lfirst(l)));
 		snprintf(querystr + strlen(querystr), sizeof(querystr) - strlen(querystr),
 				 "%sfk.%s", sep, attname);
 		sep = ", ";
@@ -2620,12 +2620,10 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
 			 relname, pkrelname);
 
 	sep="";
-	for (list=fkconstraint->pk_attrs, list2=fkconstraint->fk_attrs; 
-		 list != NIL && list2 != NIL; 
-		 list=lnext(list), list2=lnext(list2))
+	forboth(l, fkconstraint->pk_attrs, l2, fkconstraint->fk_attrs)
 	{
-		quoteOneName(attname, strVal(lfirst(list)));
-		quoteOneName(fkattname, strVal(lfirst(list2)));
+		quoteOneName(attname, strVal(lfirst(l)));
+		quoteOneName(fkattname, strVal(lfirst(l2)));
 		snprintf(querystr + strlen(querystr), sizeof(querystr) - strlen(querystr),
 				 "%spk.%s=fk.%s",
 				 sep, attname, fkattname);
@@ -2635,14 +2633,14 @@ RI_Initial_Check(FkConstraint *fkconstraint, Relation rel, Relation pkrel)
 	 * It's sufficient to test any one pk attribute for null to detect a
 	 * join failure.
 	 */
-	quoteOneName(attname, strVal(lfirst(fkconstraint->pk_attrs)));
+	quoteOneName(attname, strVal(linitial(fkconstraint->pk_attrs)));
 	snprintf(querystr + strlen(querystr), sizeof(querystr) - strlen(querystr),
 			 ") WHERE pk.%s IS NULL AND (", attname);
 
 	sep="";
-	foreach(list, fkconstraint->fk_attrs)
+	foreach(l, fkconstraint->fk_attrs)
 	{
-		quoteOneName(attname, strVal(lfirst(list)));
+		quoteOneName(attname, strVal(lfirst(l)));
 		snprintf(querystr + strlen(querystr), sizeof(querystr) - strlen(querystr),
 				 "%sfk.%s IS NOT NULL",
 				 sep, attname);
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 95e457c261fb2ae25db0b91e2e4865c58584b611..213dc61202ba768731b7cee7de45087f2de1d0bb 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
  *				back to source text
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.166 2004/05/10 22:44:46 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.167 2004/05/26 04:41:38 neilc Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -627,6 +627,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
 	Form_pg_class idxrelrec;
 	Form_pg_am	amrec;
 	List	   *indexprs;
+	ListCell   *indexpr_item;
 	List	   *context;
 	Oid			indrelid;
 	int			keyno;
@@ -691,6 +692,8 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
 	else
 		indexprs = NIL;
 
+	indexpr_item = list_head(indexprs);
+
 	context = deparse_context_for(get_rel_name(indrelid), indrelid);
 
 	/*
@@ -733,10 +736,10 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
 			/* expressional index */
 			Node	   *indexkey;
 
-			if (indexprs == NIL)
+			if (indexpr_item == NULL)
 				elog(ERROR, "too few entries in indexprs list");
-			indexkey = (Node *) lfirst(indexprs);
-			indexprs = lnext(indexprs);
+			indexkey = (Node *) lfirst(indexpr_item);
+			indexpr_item = lnext(indexpr_item);
 			/* Deparse */
 			str = deparse_expression_pretty(indexkey, context, false, false,
 											prettyFlags, 0);
@@ -1358,7 +1361,7 @@ deparse_context_for_subplan(const char *name, List *tlist,
 	List	   *attrs = NIL;
 	int			nattrs = 0;
 	int			rtablelength = length(rtable);
-	List	   *tl;
+	ListCell   *tl;
 	char		buf[32];
 
 	foreach(tl, tlist)
@@ -1526,7 +1529,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
 		 * (which can only be references to OLD and NEW).  Use the rtable
 		 * of the first query in the action list for this purpose.
 		 */
-		query = (Query *) lfirst(actions);
+		query = (Query *) linitial(actions);
 
 		/*
 		 * If the action is INSERT...SELECT, OLD/NEW have been pushed down
@@ -1556,7 +1559,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
 	/* Finally the rules actions */
 	if (length(actions) > 1)
 	{
-		List	   *action;
+		ListCell   *action;
 		Query	   *query;
 
 		appendStringInfo(buf, "(");
@@ -1579,7 +1582,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
 	{
 		Query	   *query;
 
-		query = (Query *) lfirst(actions);
+		query = (Query *) linitial(actions);
 		get_query_def(query, buf, NIL, NULL, prettyFlags, 0);
 		appendStringInfo(buf, ";");
 	}
@@ -1636,7 +1639,7 @@ make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
 		return;
 	}
 
-	query = (Query *) lfirst(actions);
+	query = (Query *) linitial(actions);
 
 	if (ev_type != '1' || ev_attr >= 0 || !is_instead ||
 		strcmp(ev_qual, "<>") != 0 || query->commandType != CMD_SELECT)
@@ -1670,7 +1673,7 @@ get_query_def(Query *query, StringInfo buf, List *parentnamespace,
 	deparse_namespace dpns;
 
 	context.buf = buf;
-	context.namespaces = lcons(&dpns, parentnamespace);
+	context.namespaces = lcons(&dpns, list_copy(parentnamespace));
 	context.varprefix = (parentnamespace != NIL ||
 						 length(query->rtable) != 1);
 	context.prettyFlags = prettyFlags;
@@ -1725,7 +1728,7 @@ get_select_query_def(Query *query, deparse_context *context,
 	StringInfo	buf = context->buf;
 	bool		force_colno;
 	char	   *sep;
-	List	   *l;
+	ListCell   *l;
 
 	/*
 	 * If the Query node has a setOperations tree, then it's the top level
@@ -1802,7 +1805,7 @@ get_basic_select_query(Query *query, deparse_context *context,
 {
 	StringInfo	buf = context->buf;
 	char	   *sep;
-	List	   *l;
+	ListCell   *l;
 	int			colno;
 
 	/*
@@ -2057,7 +2060,7 @@ get_insert_query_def(Query *query, deparse_context *context)
 	RangeTblEntry *select_rte = NULL;
 	RangeTblEntry *rte;
 	char	   *sep;
-	List	   *l;
+	ListCell   *l;
 
 	/*
 	 * If it's an INSERT ... SELECT there will be a single subquery RTE
@@ -2136,10 +2139,10 @@ get_insert_query_def(Query *query, deparse_context *context)
 static void
 get_update_query_def(Query *query, deparse_context *context)
 {
-	StringInfo	buf = context->buf;
-	char	   *sep;
-	RangeTblEntry *rte;
-	List	   *l;
+	StringInfo		 buf = context->buf;
+	char			*sep;
+	RangeTblEntry	*rte;
+	ListCell		*l;
 
 	/*
 	 * Start the query with UPDATE relname SET
@@ -2271,17 +2274,17 @@ static void
 get_names_for_var(Var *var, deparse_context *context,
 				  char **schemaname, char **refname, char **attname)
 {
-	List	   *nslist = context->namespaces;
+	ListCell   *nslist_item = list_head(context->namespaces);
 	int			sup = var->varlevelsup;
 	deparse_namespace *dpns;
 	RangeTblEntry *rte;
 
 	/* Find appropriate nesting depth */
-	while (sup-- > 0 && nslist != NIL)
-		nslist = lnext(nslist);
-	if (nslist == NIL)
+	while (sup-- > 0 && nslist_item != NULL)
+		nslist_item = lnext(nslist_item);
+	if (nslist_item == NULL)
 		elog(ERROR, "bogus varlevelsup: %d", var->varlevelsup);
-	dpns = (deparse_namespace *) lfirst(nslist);
+	dpns = (deparse_namespace *) lfirst(nslist_item);
 
 	/* Find the relevant RTE */
 	if (var->varno >= 1 && var->varno <= length(dpns->rtable))
@@ -2342,13 +2345,13 @@ get_names_for_var(Var *var, deparse_context *context,
 static RangeTblEntry *
 find_rte_by_refname(const char *refname, deparse_context *context)
 {
-	RangeTblEntry *result = NULL;
-	List	   *nslist;
+	RangeTblEntry  *result = NULL;
+	ListCell	   *nslist;
 
 	foreach(nslist, context->namespaces)
 	{
 		deparse_namespace *dpns = (deparse_namespace *) lfirst(nslist);
-		List	   *rtlist;
+		ListCell	   *rtlist;
 
 		foreach(rtlist, dpns->rtable)
 		{
@@ -2396,7 +2399,7 @@ get_simple_binary_op_name(OpExpr *expr)
 	if (length(args) == 2)
 	{
 		/* binary operator */
-		Node	   *arg1 = (Node *) lfirst(args);
+		Node	   *arg1 = (Node *) linitial(args);
 		Node	   *arg2 = (Node *) lsecond(args);
 		const char *op;
 
@@ -2501,7 +2504,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
 					 * Operators are same priority --- can skip parens
 					 * only if we have (a - b) - c, not a - (b - c).
 					 */
-					if (node == (Node *) lfirst(((OpExpr *) parentNode)->args))
+					if (node == (Node *) linitial(((OpExpr *) parentNode)->args))
 						return true;
 
 					return false;
@@ -2759,8 +2762,8 @@ get_rule_expr(Node *node, deparse_context *context,
 				ArrayRef   *aref = (ArrayRef *) node;
 				bool		savevarprefix = context->varprefix;
 				bool		need_parens;
-				List	   *lowlist;
-				List	   *uplist;
+				ListCell   *lowlist_item;
+				ListCell   *uplist_item;
 
 				/*
 				 * If we are doing UPDATE array[n] = expr, we need to
@@ -2783,18 +2786,19 @@ get_rule_expr(Node *node, deparse_context *context,
 				if (need_parens)
 					appendStringInfoChar(buf, ')');
 				context->varprefix = savevarprefix;
-				lowlist = aref->reflowerindexpr;
-				foreach(uplist, aref->refupperindexpr)
+				lowlist_item = list_head(aref->reflowerindexpr);
+				foreach(uplist_item, aref->refupperindexpr)
 				{
 					appendStringInfo(buf, "[");
-					if (lowlist)
+					if (lowlist_item)
 					{
-						get_rule_expr((Node *) lfirst(lowlist), context,
+						get_rule_expr((Node *) lfirst(lowlist_item), context,
 									  false);
 						appendStringInfo(buf, ":");
-						lowlist = lnext(lowlist);
+						lowlist_item = lnext(lowlist_item);
 					}
-					get_rule_expr((Node *) lfirst(uplist), context, false);
+					get_rule_expr((Node *) lfirst(uplist_item),
+								  context, false);
 					appendStringInfo(buf, "]");
 				}
 				if (aref->refassgnexpr)
@@ -2818,7 +2822,7 @@ get_rule_expr(Node *node, deparse_context *context,
 			{
 				DistinctExpr *expr = (DistinctExpr *) node;
 				List	   *args = expr->args;
-				Node	   *arg1 = (Node *) lfirst(args);
+				Node	   *arg1 = (Node *) linitial(args);
 				Node	   *arg2 = (Node *) lsecond(args);
 
 				if (!PRETTY_PAREN(context))
@@ -2835,7 +2839,7 @@ get_rule_expr(Node *node, deparse_context *context,
 			{
 				ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
 				List	   *args = expr->args;
-				Node	   *arg1 = (Node *) lfirst(args);
+				Node	   *arg1 = (Node *) linitial(args);
 				Node	   *arg2 = (Node *) lsecond(args);
 
 				if (!PRETTY_PAREN(context))
@@ -2856,20 +2860,22 @@ get_rule_expr(Node *node, deparse_context *context,
 		case T_BoolExpr:
 			{
 				BoolExpr   *expr = (BoolExpr *) node;
-				List	   *args = expr->args;
+				Node	   *first_arg = linitial(expr->args);
+				ListCell   *arg = lnext(list_head(expr->args));
 
 				switch (expr->boolop)
 				{
 					case AND_EXPR:
 						if (!PRETTY_PAREN(context))
 							appendStringInfoChar(buf, '(');
-						get_rule_expr_paren((Node *) lfirst(args), context,
+						get_rule_expr_paren(first_arg, context,
 											false, node);
-						while ((args = lnext(args)) != NIL)
+						while (arg)
 						{
 							appendStringInfo(buf, " AND ");
-							get_rule_expr_paren((Node *) lfirst(args), context,
+							get_rule_expr_paren((Node *) lfirst(arg), context,
 												false, node);
+							arg = lnext(arg);
 						}
 						if (!PRETTY_PAREN(context))
 							appendStringInfoChar(buf, ')');
@@ -2878,13 +2884,14 @@ get_rule_expr(Node *node, deparse_context *context,
 					case OR_EXPR:
 						if (!PRETTY_PAREN(context))
 							appendStringInfoChar(buf, '(');
-						get_rule_expr_paren((Node *) lfirst(args), context,
+						get_rule_expr_paren(first_arg, context,
 											false, node);
-						while ((args = lnext(args)) != NIL)
+						while (arg)
 						{
 							appendStringInfo(buf, " OR ");
-							get_rule_expr_paren((Node *) lfirst(args), context,
+							get_rule_expr_paren((Node *) lfirst(arg), context,
 												false, node);
+							arg = lnext(arg);
 						}
 						if (!PRETTY_PAREN(context))
 							appendStringInfoChar(buf, ')');
@@ -2894,7 +2901,7 @@ get_rule_expr(Node *node, deparse_context *context,
 						if (!PRETTY_PAREN(context))
 							appendStringInfoChar(buf, '(');
 						appendStringInfo(buf, "NOT ");
-						get_rule_expr_paren((Node *) lfirst(args), context,
+						get_rule_expr_paren(first_arg, context,
 											false, node);
 						if (!PRETTY_PAREN(context))
 							appendStringInfoChar(buf, ')');
@@ -2989,7 +2996,7 @@ get_rule_expr(Node *node, deparse_context *context,
 		case T_CaseExpr:
 			{
 				CaseExpr   *caseexpr = (CaseExpr *) node;
-				List	   *temp;
+				ListCell   *temp;
 
 				appendContextKeyword(context, "CASE",
 									 0, PRETTYINDENT_VAR, 0);
@@ -3035,7 +3042,7 @@ get_rule_expr(Node *node, deparse_context *context,
 		case T_ArrayExpr:
 			{
 				ArrayExpr  *arrayexpr = (ArrayExpr *) node;
-				List	   *element;
+				ListCell   *element;
 				char	   *sep;
 
 				appendStringInfo(buf, "ARRAY[");
@@ -3055,7 +3062,7 @@ get_rule_expr(Node *node, deparse_context *context,
 		case T_RowExpr:
 			{
 				RowExpr	   *rowexpr = (RowExpr *) node;
-				List	   *arg;
+				ListCell   *arg;
 				char	   *sep;
 
 				/*
@@ -3082,7 +3089,7 @@ get_rule_expr(Node *node, deparse_context *context,
 		case T_CoalesceExpr:
 			{
 				CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
-				List	   *arg;
+				ListCell   *arg;
 				char	   *sep;
 
 				appendStringInfo(buf, "COALESCE(");
@@ -3102,7 +3109,7 @@ get_rule_expr(Node *node, deparse_context *context,
 		case T_NullIfExpr:
 			{
 				NullIfExpr *nullifexpr = (NullIfExpr *) node;
-				List	   *arg;
+				ListCell   *arg;
 				char	   *sep;
 
 				appendStringInfo(buf, "NULLIF(");
@@ -3239,7 +3246,7 @@ get_oper_expr(OpExpr *expr, deparse_context *context)
 	if (length(args) == 2)
 	{
 		/* binary operator */
-		Node	   *arg1 = (Node *) lfirst(args);
+		Node	   *arg1 = (Node *) linitial(args);
 		Node	   *arg2 = (Node *) lsecond(args);
 
 		get_rule_expr_paren(arg1, context, true, (Node *) expr);
@@ -3252,7 +3259,7 @@ get_oper_expr(OpExpr *expr, deparse_context *context)
 	else
 	{
 		/* unary operator --- but which side? */
-		Node	   *arg = (Node *) lfirst(args);
+		Node	   *arg = (Node *) linitial(args);
 		HeapTuple	tp;
 		Form_pg_operator optup;
 
@@ -3298,7 +3305,7 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
 	Oid			funcoid = expr->funcid;
 	Oid			argtypes[FUNC_MAX_ARGS];
 	int			nargs;
-	List	   *l;
+	ListCell   *l;
 	char	   *sep;
 
 	/*
@@ -3308,7 +3315,7 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
 	 */
 	if (expr->funcformat == COERCE_IMPLICIT_CAST && !showimplicit)
 	{
-		get_rule_expr_paren((Node *) lfirst(expr->args), context,
+		get_rule_expr_paren((Node *) linitial(expr->args), context,
 							showimplicit, (Node *) expr);
 		return;
 	}
@@ -3320,7 +3327,7 @@ get_func_expr(FuncExpr *expr, deparse_context *context,
 	if (expr->funcformat == COERCE_EXPLICIT_CAST ||
 		expr->funcformat == COERCE_IMPLICIT_CAST)
 	{
-		Node	   *arg = lfirst(expr->args);
+		Node	   *arg = linitial(expr->args);
 		Oid			rettype = expr->funcresulttype;
 		int32		coercedTypmod;
 
@@ -3424,7 +3431,7 @@ strip_type_coercion(Node *expr, Oid resultType)
 		if (exprIsLengthCoercion(expr, NULL))
 			return expr;
 
-		return (Node *) lfirst(func->args);
+		return (Node *) linitial(func->args);
 	}
 
 	return expr;
@@ -3580,7 +3587,7 @@ get_sublink_expr(SubLink *sublink, deparse_context *context)
 {
 	StringInfo	buf = context->buf;
 	Query	   *query = (Query *) (sublink->subselect);
-	List	   *l;
+	ListCell   *l;
 	char	   *sep;
 	bool		need_paren;
 
@@ -3625,7 +3632,7 @@ get_sublink_expr(SubLink *sublink, deparse_context *context)
 
 		case ANY_SUBLINK:
 			if (length(sublink->operName) == 1 &&
-				strcmp(strVal(lfirst(sublink->operName)), "=") == 0)
+				strcmp(strVal(linitial(sublink->operName)), "=") == 0)
 			{
 				/* Represent = ANY as IN */
 				appendStringInfo(buf, "IN ");
@@ -3680,7 +3687,7 @@ get_from_clause(Query *query, deparse_context *context)
 {
 	StringInfo	buf = context->buf;
 	bool		first = true;
-	List	   *l;
+	ListCell   *l;
 
 	/*
 	 * We use the query's jointree as a guide to what to print.  However,
@@ -3763,12 +3770,12 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
 			gavealias = true;
 			if (rte->alias->colnames != NIL && coldeflist == NIL)
 			{
-				List	   *col;
+				ListCell   *col;
 
 				appendStringInfoChar(buf, '(');
 				foreach(col, rte->alias->colnames)
 				{
-					if (col != rte->alias->colnames)
+					if (col != list_head(rte->alias->colnames))
 						appendStringInfo(buf, ", ");
 					appendStringInfoString(buf,
 										   quote_identifier(strVal(lfirst(col))));
@@ -3897,12 +3904,12 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
 		{
 			if (j->using)
 			{
-				List	   *col;
+				ListCell   *col;
 
 				appendStringInfo(buf, " USING (");
 				foreach(col, j->using)
 				{
-					if (col != j->using)
+					if (col != list_head(j->using))
 						appendStringInfo(buf, ", ");
 					appendStringInfoString(buf,
 								quote_identifier(strVal(lfirst(col))));
@@ -3929,12 +3936,12 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
 							 quote_identifier(j->alias->aliasname));
 			if (j->alias->colnames != NIL)
 			{
-				List	   *col;
+				ListCell   *col;
 
 				appendStringInfoChar(buf, '(');
 				foreach(col, j->alias->colnames)
 				{
-					if (col != j->alias->colnames)
+					if (col != list_head(j->alias->colnames))
 						appendStringInfo(buf, ", ");
 					appendStringInfoString(buf,
 								  quote_identifier(strVal(lfirst(col))));
@@ -3958,7 +3965,7 @@ static void
 get_from_clause_coldeflist(List *coldeflist, deparse_context *context)
 {
 	StringInfo	buf = context->buf;
-	List	   *col;
+	ListCell   *col;
 	int			i = 0;
 
 	appendStringInfoChar(buf, '(');
@@ -4337,20 +4344,21 @@ generate_operator_name(Oid operid, Oid arg1, Oid arg2)
 static void
 print_operator_name(StringInfo buf, List *opname)
 {
-	int			nnames = length(opname);
+	ListCell	*op = list_head(opname);
+	int			 nnames = length(opname);
 
 	if (nnames == 1)
-		appendStringInfoString(buf, strVal(lfirst(opname)));
+		appendStringInfoString(buf, strVal(lfirst(op)));
 	else
 	{
 		appendStringInfo(buf, "OPERATOR(");
 		while (nnames-- > 1)
 		{
 			appendStringInfo(buf, "%s.",
-							 quote_identifier(strVal(lfirst(opname))));
-			opname = lnext(opname);
+							 quote_identifier(strVal(lfirst(op))));
+			op = lnext(op);
 		}
-		appendStringInfo(buf, "%s)", strVal(lfirst(opname)));
+		appendStringInfo(buf, "%s)", strVal(lfirst(op)));
 	}
 }
 
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index ded7260c784d1c2356dd60802a4489f52d93cff5..cd9a6444d41d90272e82f545e8b3091c8f6e7065 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.158 2004/02/27 21:44:34 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.159 2004/05/26 04:41:39 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1936,7 +1936,7 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
 	List	   *allvars = NIL;
 	List	   *varinfos = NIL;
 	double		numdistinct;
-	List	   *l;
+	ListCell   *l;
 	typedef struct
 	{							/* varinfos is a List of these */
 		Var		   *var;
@@ -1987,14 +1987,14 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
 		VariableStatData vardata;
 		double		ndistinct;
 		bool		keep = true;
-		List	   *l2;
+		ListCell   *l2;
 
 		examine_variable(root, (Node *) var, 0, &vardata);
 		ndistinct = get_variable_numdistinct(&vardata);
 		ReleaseVariableStats(vardata);
 
 		/* cannot use foreach here because of possible lremove */
-		l2 = varinfos;
+		l2 = list_head(varinfos);
 		while (l2)
 		{
 			MyVarInfo  *varinfo = (MyVarInfo *) lfirst(l2);
@@ -2043,7 +2043,7 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
 
 	do
 	{
-		MyVarInfo  *varinfo1 = (MyVarInfo *) lfirst(varinfos);
+		MyVarInfo  *varinfo1 = (MyVarInfo *) linitial(varinfos);
 		RelOptInfo *rel = find_base_rel(root, varinfo1->var->varno);
 		double		reldistinct = varinfo1->ndistinct;
 		List	   *newvarinfos = NIL;
@@ -2052,7 +2052,7 @@ estimate_num_groups(Query *root, List *groupExprs, double input_rows)
 		 * Get the largest numdistinct estimate of the Vars for this rel.
 		 * Also, construct new varinfos list of remaining Vars.
 		 */
-		foreach(l, lnext(varinfos))
+		for_each_cell(l, lnext(list_head(varinfos)))
 		{
 			MyVarInfo  *varinfo2 = (MyVarInfo *) lfirst(l);
 
@@ -2844,7 +2844,7 @@ get_restriction_variable(Query *root, List *args, int varRelid,
 	if (length(args) != 2)
 		return false;
 
-	left = (Node *) lfirst(args);
+	left = (Node *) linitial(args);
 	right = (Node *) lsecond(args);
 
 	/*
@@ -2895,7 +2895,7 @@ get_join_variables(Query *root, List *args,
 	if (length(args) != 2)
 		elog(ERROR, "join operator should take two arguments");
 
-	left = (Node *) lfirst(args);
+	left = (Node *) linitial(args);
 	right = (Node *) lsecond(args);
 
 	examine_variable(root, left, 0, vardata1);
@@ -3033,16 +3033,16 @@ examine_variable(Query *root, Node *node, int varRelid,
 		 * different index opclasses; if so, we need to pick one that
 		 * matches the operator we are estimating for.  FIXME later.
 		 */
-		List	   *ilist;
+		ListCell   *ilist;
 
 		foreach(ilist, onerel->indexlist)
 		{
 			IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
-			List	   *indexprs;
+			ListCell   *indexpr_item;
 			int			pos;
 
-			indexprs = index->indexprs;
-			if (indexprs == NIL)
+			indexpr_item = list_head(index->indexprs);
+			if (indexpr_item == NULL)
 				continue;		/* no expressions here... */
 
 			/*
@@ -3058,9 +3058,9 @@ examine_variable(Query *root, Node *node, int varRelid,
 				{
 					Node	   *indexkey;
 
-					if (indexprs == NIL)
+					if (indexpr_item == NULL)
 						elog(ERROR, "too few entries in indexprs list");
-					indexkey = (Node *) lfirst(indexprs);
+					indexkey = (Node *) lfirst(indexpr_item);
 					if (indexkey && IsA(indexkey, RelabelType))
 						indexkey = (Node *) ((RelabelType *) indexkey)->arg;
 					if (equal(node, indexkey))
@@ -3081,7 +3081,7 @@ examine_variable(Query *root, Node *node, int varRelid,
 						if (vardata->statsTuple)
 							break;
 					}
-					indexprs = lnext(indexprs);
+					indexpr_item = lnext(indexpr_item);
 				}
 			}
 			if (vardata->statsTuple)
diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c
index 8433bc98c4df79dc97ee47a8c89f4347a72419bd..f8f207d72abda1a97ad5dfad15e8e57fcee3b471 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/tid.c,v 1.43 2004/05/07 00:24:58 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/tid.c,v 1.44 2004/05/26 04:41:39 neilc Exp $
  *
  * NOTES
  *	  input routine largely stolen from boxin().
@@ -241,7 +241,7 @@ currtid_for_view(Relation viewrel, ItemPointer tid)
 
 			if (length(rewrite->actions) != 1)
 				elog(ERROR, "only one select rule is allowed in views");
-			query = (Query *) lfirst(rewrite->actions);
+			query = (Query *) linitial(rewrite->actions);
 			tle = get_tle_by_resno(query->targetList, tididx+1);
 			if (tle && tle->expr && IsA(tle->expr, Var))
 			{
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index f329486321d96c8af9fe9b9e28a5196e65cb7f36..410faad692598c1ac7a85badbcc7155fad44d0fd 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.112 2004/02/21 00:34:53 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.113 2004/05/26 04:41:39 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1623,7 +1623,7 @@ textToQualifiedNameList(text *textval, const char *caller)
 	char	   *rawname;
 	List	   *result = NIL;
 	List	   *namelist;
-	List	   *l;
+	ListCell   *l;
 
 	/* Convert to C string (handles possible detoasting). */
 	/* Note we rely on being able to modify rawname below. */
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 5732e5ab4244267d363a3d509eb899a697f339ae..5e91a7283ecc0ae100a1f1da7d4124e5e463557d 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.111 2003/11/29 19:52:00 pgsql Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.112 2004/05/26 04:41:40 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1317,6 +1317,7 @@ SearchCatCacheList(CatCache *cache,
 	CatCList   *cl;
 	CatCTup    *ct;
 	List	   *ctlist;
+	ListCell   *ctlist_item;
 	int			nmembers;
 	Relation	relation;
 	SysScanDesc scandesc;
@@ -1510,15 +1511,16 @@ SearchCatCacheList(CatCache *cache,
 	cl->hash_value = lHashValue;
 	cl->n_members = nmembers;
 	/* The list is backwards because we built it with lcons */
+	ctlist_item = list_head(ctlist);
 	for (i = nmembers; --i >= 0;)
 	{
-		cl->members[i] = ct = (CatCTup *) lfirst(ctlist);
+		cl->members[i] = ct = (CatCTup *) lfirst(ctlist_item);
 		Assert(ct->c_list == NULL);
 		ct->c_list = cl;
 		/* mark list dead if any members already dead */
 		if (ct->dead)
 			cl->dead = true;
-		ctlist = lnext(ctlist);
+		ctlist_item = lnext(ctlist_item);
 	}
 
 	DLAddHead(&cache->cc_lists, &cl->cache_elem);
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0e4a31745fda0096218b549cd1e006c7bed8d3c5..4d8190a7b0faad1bcba88e547046b91eac5be3ea 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.202 2004/05/08 19:09:25 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.203 2004/05/26 04:41:40 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1872,7 +1872,7 @@ RelationCacheInvalidate(void)
 	Relation	relation;
 	List	   *rebuildFirstList = NIL;
 	List	   *rebuildList = NIL;
-	List	   *l;
+	ListCell   *l;
 
 	/* Phase 1 */
 	hash_seq_init(&status, RelationIdCache);
@@ -2577,23 +2577,24 @@ RelationGetIndexList(Relation relation)
 static List *
 insert_ordered_oid(List *list, Oid datum)
 {
-	List	   *l;
+	ListCell *prev;
 
 	/* Does the datum belong at the front? */
-	if (list == NIL || datum < lfirsto(list))
-		return lconso(datum, list);
+	if (list == NIL || datum < linitial_oid(list))
+		return lcons_oid(datum, list);
 	/* No, so find the entry it belongs after */
-	l = list;
+	prev = list_head(list);
 	for (;;)
 	{
-		List	   *n = lnext(l);
+		ListCell *curr = lnext(prev);
 
-		if (n == NIL || datum < lfirsto(n))
-			break;				/* it belongs before n */
-		l = n;
+		if (curr == NULL || datum < lfirst_oid(curr))
+			break;		/* it belongs after 'prev', before 'curr' */
+
+		prev = curr;
 	}
-	/* Insert datum into list after item l */
-	lnext(l) = lconso(datum, lnext(l));
+	/* Insert datum into list after 'prev' */
+	lappend_cell_oid(list, prev, datum);
 	return list;
 }
 
diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index 7a8e67c83c8f82944b421130b2b5db0209833239..b3ef61c2d723ccf68eee0153b65f23caf95c84f1 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -36,7 +36,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.5 2004/04/01 21:28:45 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/cache/typcache.c,v 1.6 2004/05/26 04:41:40 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -432,7 +432,7 @@ assign_record_type_typmod(TupleDesc tupDesc)
 	Oid			hashkey[REC_HASH_KEYS];
 	bool		found;
 	int			i;
-	List	   *l;
+	ListCell   *l;
 	int32		newtypmod;
 	MemoryContext oldcxt;
 
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 75cc07a518d163ac3936677542c4ca6e12f00e47..6507891d66d932892d78a01b8e7443aad77ed2e8 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.124 2004/04/19 17:42:58 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.125 2004/05/26 04:41:43 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -883,7 +883,7 @@ process_preload_libraries(char *preload_libraries_string)
 {
 	char	   *rawstring;
 	List	   *elemlist;
-	List	   *l;
+	ListCell   *l;
 
 	if (preload_libraries_string == NULL)
 		return;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 8a51e8aa0491ce565b2f45a47f9baeb7aceecbb7..1cfc3e0346b5b1b16d2783cef89432eff8132148 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
  * Written by Peter Eisentraut <peter_e@gmx.net>.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.206 2004/05/21 05:08:03 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.207 2004/05/26 04:41:43 neilc Exp $
  *
  *--------------------------------------------------------------------
  */
@@ -3290,7 +3290,7 @@ flatten_set_variable_args(const char *name, List *args)
 	struct config_generic *record;
 	int			flags;
 	StringInfoData buf;
-	List	   *l;
+	ListCell   *l;
 
 	/*
 	 * Fast path if just DEFAULT.  We do not check the variable name in
@@ -3310,7 +3310,7 @@ flatten_set_variable_args(const char *name, List *args)
 
 	/* Complain if list input and non-list variable */
 	if ((flags & GUC_LIST_INPUT) == 0 &&
-		lnext(args) != NIL)
+		list_length(args) != 1)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("SET %s takes only one argument", name)));
@@ -3322,7 +3322,7 @@ flatten_set_variable_args(const char *name, List *args)
 		A_Const    *arg = (A_Const *) lfirst(l);
 		char	   *val;
 
-		if (l != args)
+		if (l != list_head(args))
 			appendStringInfo(&buf, ", ");
 
 		if (!IsA(arg, A_Const))
@@ -4430,7 +4430,7 @@ assign_log_destination(const char *value, bool doit, GucSource source)
 {
 	char *rawstring;
 	List *elemlist;
-	List *l;
+	ListCell *l;
 	unsigned int  newlogdest = 0;
  
 	/* Need a modifiable copy of string */
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 20c1b08f5c5c60b05e8cb17e56832f2a0eec3be1..6c37048229ab68b5479d3f58b8a46548f68a58e3 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.154 2004/05/10 22:44:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.155 2004/05/26 04:41:45 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -192,6 +192,8 @@ typedef enum NodeTag
 	 * TAGS FOR LIST NODES (pg_list.h)
 	 */
 	T_List,
+	T_IntList,
+	T_OidList,
 
 	/*
 	 * TAGS FOR PARSE TREE NODES (parsenodes.h)
diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h
index 31566a29c9f0a83757d341011c5f0205b61ee38e..31c90de88c92e1abeca5af0dc1c6d02912b47ce2 100644
--- a/src/include/nodes/pg_list.h
+++ b/src/include/nodes/pg_list.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/pg_list.h,v 1.43 2004/01/07 18:43:36 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/pg_list.h,v 1.44 2004/05/26 04:41:45 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,140 +16,324 @@
 
 #include "nodes/nodes.h"
 
-/* ----------------------------------------------------------------
- *						node definitions
- * ----------------------------------------------------------------
+/*
+ * As a temporary measure, enable the compatibility API unless the
+ * include site specifically disabled it. Once the rest of the source
+ * tree has been converted to the new API, this will be removed.
  */
+#ifndef DISABLE_LIST_COMPAT
+#define ENABLE_LIST_COMPAT
+#endif
 
-/*----------------------
- *		List node
+/*
+ * This package implements singly-linked homogeneous lists. It is
+ * important to have constant-time length, append, and prepend
+ * operations. To achieve this, we deal with two distinct data
+ * structures:
+ *
+ *		1. A set of "list cells": each cell contains a data field and
+ *		   a link to the next cell in the list or NULL.
+ *		2. A single structure containing metadata about the list: the
+ *		   type of the list, pointers to the head and tail cells, and
+ *		   the length of the list.
  *
  * We support three types of lists:
- *	lists of pointers (in practice always pointers to Nodes, but declare as
- *		"void *" to minimize casting annoyances)
- *	lists of integers
- *	lists of Oids
  *
- * (At this writing, ints and Oids are the same size, but they may not always
- * be so; try to be careful to maintain the distinction.)
- *----------------------
+ *	T_List: lists of pointers
+ *      (in practice usually pointers to Nodes, but not always;
+ *      declared as "void *" to minimize casting annoyances)
+ *	T_IntList: lists of integers
+ *	T_OidList: lists of Oids
+ *
+ * (At the moment, ints and Oids are the same size, but they may not
+ * always be so; try to be careful to maintain the distinction.)
  */
-typedef struct List
+
+#define LIST_CELL_TYPE ListCell
+
+typedef struct ListCell ListCell;
+typedef struct List List;
+
+struct List
+{
+	NodeTag		 type;	/* T_List, T_IntList, or T_OidList */
+	int			 length;
+	ListCell *head;
+	ListCell *tail;
+};
+
+struct ListCell
 {
-	NodeTag		type;
 	union
 	{
-		void	   *ptr_value;
-		int			int_value;
-		Oid			oid_value;
-	}			elem;
-	struct List *next;
-} List;
+		void	*ptr_value;
+		int		 int_value;
+		Oid		 oid_value;
+	} data;
+	ListCell *next;
+};
 
-#define    NIL			((List *) NULL)
+/*
+ * The *only* valid representation of an empty list is NIL; in other
+ * words, a non-NIL list is guaranteed to have length >= 1 and
+ * head/tail != NULL
+ */
+#define NIL						((List *) NULL)
 
-/* ----------------
- *		accessor macros
- *
- * The general naming convention is that the base name xyz() is for the
- * pointer version, xyzi() is for integers, xyzo() is for Oids.  We don't
- * bother with multiple names if the same routine can handle all cases.
- * ----------------
+/*
+ * These routines are used frequently. However, we can't implement
+ * them as macros, since we want to avoid double-evaluation of macro
+ * arguments. Therefore, we implement them using GCC inline functions,
+ * and as regular functions with non-GCC compilers.
+ */
+#ifdef __GNUC__
+
+static __inline__ ListCell *
+list_head(List *l)
+{
+	return l ? l->head : NULL;
+}
+
+static __inline__ ListCell *
+list_tail(List *l)
+{
+	return l ? l->tail : NULL;
+}
+
+static __inline__ int
+list_length(List *l)
+{
+	return l ? l->length : 0;
+}
+
+#else
+
+extern ListCell *list_head(List *l);
+extern ListCell *list_tail(List *l);
+extern int list_length(List *l);
+
+#endif /* __GNUC__ */
+
+/*
+ * NB: There is an unfortunate legacy from a previous incarnation of
+ * the List API: the macro lfirst() was used to mean "the data in this
+ * cons cell". To avoid changing every usage of lfirst(), that meaning
+ * has been kept. As a result, lfirst() takes a ListCell and returns
+ * the data it contains; to get the data in the _first_ cell of a
+ * List, use linitial(). Worse, lsecond() is more closely related to
+ * linitial() than lfirst(): given a List, lsecond() returns the data
+ * in the second cons cell.
  */
 
-#define lfirst(l)								((l)->elem.ptr_value)
-#define lfirsti(l)								((l)->elem.int_value)
-#define lfirsto(l)								((l)->elem.oid_value)
+#define lnext(lc)				((lc)->next)
+#define lfirst(lc)				((lc)->data.ptr_value)
+#define lfirst_int(lc)			((lc)->data.int_value)
+#define lfirst_oid(lc)			((lc)->data.oid_value)
 
-#define lnext(l)								((l)->next)
+#define linitial(l)				lfirst(list_head(l))
+#define linitial_int(l)			lfirst_int(list_head(l))
+#define linitial_oid(l)			lfirst_oid(list_head(l))
 
-#define lsecond(l)								lfirst(lnext(l))
+#define lsecond(l)				lfirst(lnext(list_head(l)))
+#define lsecond_int(l)			lfirst_int(lnext(list_head(l)))
+#define lsecond_oid(l)			lfirst_oid(lnext(list_head(l)))
 
-#define lthird(l)								lfirst(lnext(lnext(l)))
+#define lthird(l)				lfirst(lnext(lnext(list_head(l))))
+#define lthird_int(l)			lfirst_int(lnext(lnext(list_head(l))))
+#define lthird_oid(l)			lfirst_oid(lnext(lnext(list_head(l))))
 
-#define lfourth(l)								lfirst(lnext(lnext(lnext(l))))
+#define lfourth(l)				lfirst(lnext(lnext(lnext(list_head(l)))))
+#define lfourth_int(l)			lfirst_int(lnext(lnext(lnext(list_head(l)))))
+#define lfourth_oid(l)			lfirst_oid(lnext(lnext(lnext(list_head(l)))))
+
+/*
+ * Convenience macros for building fixed-length lists
+ */
+#define list_make1(x1)				lcons(x1, NIL)
+#define list_make2(x1,x2)			lcons(x1, list_make1(x2))
+#define list_make3(x1,x2,x3)		lcons(x1, list_make2(x2, x3))
+#define list_make4(x1,x2,x3,x4)		lcons(x1, list_make3(x2, x3, x4))
+
+#define list_make1_int(x1)			lcons_int(x1, NIL)
+#define list_make2_int(x1,x2)		lcons_int(x1, list_make1_int(x2))
+#define list_make3_int(x1,x2,x3)	lcons_int(x1, list_make2_int(x2, x3))
+#define list_make4_int(x1,x2,x3,x4)	lcons_int(x1, list_make3_int(x2, x3, x4))
+
+#define list_make1_oid(x1)			lcons_oid(x1, NIL)
+#define list_make2_oid(x1,x2)		lcons_oid(x1, list_make1_oid(x2))
+#define list_make3_oid(x1,x2,x3)	lcons_oid(x1, list_make2_oid(x2, x3))
+#define list_make4_oid(x1,x2,x3,x4)	lcons_oid(x1, list_make3_oid(x2, x3, x4))
 
 /*
  * foreach -
  *	  a convenience macro which loops through the list
  */
-#define foreach(_elt_,_list_)	\
-	for (_elt_ = (_list_); _elt_ != NIL; _elt_ = lnext(_elt_))
+#define foreach(cell, l)	\
+	for ((cell) = list_head(l); (cell) != NULL; (cell) = lnext(cell))
 
 /*
- * Convenience macros for building fixed-length lists
+ * for_each_cell -
+ *	  a convenience macro which loops through a list starting from a
+ *	  specified cell
  */
-#define makeList1(x1)				lcons(x1, NIL)
-#define makeList2(x1,x2)			lcons(x1, makeList1(x2))
-#define makeList3(x1,x2,x3)			lcons(x1, makeList2(x2,x3))
-#define makeList4(x1,x2,x3,x4)		lcons(x1, makeList3(x2,x3,x4))
+#define for_each_cell(cell, l)	\
+	for ((cell) = (l); (cell) != NULL; (cell) = lnext(cell))
 
-#define makeListi1(x1)				lconsi(x1, NIL)
-#define makeListi2(x1,x2)			lconsi(x1, makeListi1(x2))
+/*
+ * forboth -
+ *    a convenience macro for advancing through two linked lists
+ *    simultaneously. This macro loops through both lists at the same
+ *    time, stopping when either list runs out of elements. Depending
+ *    on the requirements of the call site, it may also be wise to
+ *    ensure that the lengths of the two lists are equal.
+ */
+#define forboth(cell1, list1, cell2, list2)							\
+	for ((cell1) = list_head(list1), (cell2) = list_head(list2);	\
+		 (cell1) != NULL && (cell2) != NULL;						\
+		 (cell1) = lnext(cell1), (cell2) = lnext(cell2))
 
-#define makeListo1(x1)				lconso(x1, NIL)
-#define makeListo2(x1,x2)			lconso(x1, makeListo1(x2))
+extern List *lappend(List *list, void *datum);
+extern List *lappend_int(List *list, int datum);
+extern List *lappend_oid(List *list, Oid datum);
+
+extern ListCell *lappend_cell(List *list, ListCell *prev, void *datum);
+extern ListCell *lappend_cell_int(List *list, ListCell *prev, int datum);
+extern ListCell *lappend_cell_oid(List *list, ListCell *prev, Oid datum);
+
+extern List *lcons(void *datum, List *list);
+extern List *lcons_int(int datum, List *list);
+extern List *lcons_oid(Oid datum, List *list);
+
+extern List *list_concat(List *list1, List *list2);
+extern List *list_truncate(List *list, int new_size);
+
+extern void *list_nth(List *list, int n);
+extern int list_nth_int(List *list, int n);
+extern Oid list_nth_oid(List *list, int n);
+
+extern bool list_member(List *list, void *datum);
+extern bool list_member_ptr(List *list, void *datum);
+extern bool list_member_int(List *list, int datum);
+extern bool list_member_oid(List *list, Oid datum);
+
+extern List *list_delete(List *list, void *datum);
+extern List *list_delete_ptr(List *list, void *datum);
+extern List *list_delete_int(List *list, int datum);
+extern List *list_delete_oid(List *list, Oid datum);
+extern List *list_delete_first(List *list);
+extern List *list_delete_cell(List *list, ListCell *cell, ListCell *prev);
+
+extern List *list_union(List *list1, List *list2);
+extern List *list_union_ptr(List *list1, List *list2);
+extern List *list_union_int(List *list1, List *list2);
+extern List *list_union_oid(List *list1, List *list2);
+
+extern List *list_difference(List *list1, List *list2);
+extern List *list_difference_ptr(List *list1, List *list2);
+extern List *list_difference_int(List *list1, List *list2);
+extern List *list_difference_oid(List *list1, List *list2);
+
+extern void list_free(List *list);
+extern void list_free_deep(List *list);
+
+extern List *list_copy(List *list);
+extern List *list_copy_tail(List *list, int nskip);
 
 /*
- * FastList is an optimization for building large lists.  The conventional
- * way to build a list is repeated lappend() operations, but that is O(N^2)
- * in the number of list items, which gets tedious for large lists.
- *
- * Note: there are some hacks in gram.y that rely on the head pointer (the
- * value-as-list) being the first field.
+ * To ease migration to the new list API, a set of compatibility
+ * macros are provided that reduce the impact of the list API changes
+ * as far as possible. Until client code has been rewritten to use the
+ * new list API, the ENABLE_LIST_COMPAT symbol can be defined before
+ * including pg_list.h
+ */
+#ifdef ENABLE_LIST_COMPAT
+
+#define lfirsti(lc)					lfirst_int(lc)
+#define lfirsto(lc)					lfirst_oid(lc)
+
+#define llast(l)					lfirst(list_tail(l))
+
+#define makeList1(x1)				list_make1(x1)
+#define makeList2(x1, x2)			list_make2(x1, x2)
+#define makeList3(x1, x2, x3)		list_make3(x1, x2, x3)
+#define makeList4(x1, x2, x3, x4)	list_make4(x1, x2, x3, x4)
+
+#define makeListi1(x1)				list_make1_int(x1)
+#define makeListi2(x1, x2)			list_make2_int(x1, x2)
+
+#define makeListo1(x1)				list_make1_oid(x1)
+#define makeListo2(x1, x2)			list_make2_oid(x1, x2)
+
+#define lconsi(datum, list)			lcons_int(datum, list)
+#define lconso(datum, list)			lcons_oid(datum, list)
+
+#define lappendi(list, datum)		lappend_int(list, datum)
+#define lappendo(list, datum)		lappend_oid(list, datum)
+
+#define nconc(l1, l2)				list_concat(l1, l2)
+
+#define nth(n, list)				list_nth(list, n)
+
+#define member(datum, list)			list_member(list, datum)
+#define ptrMember(datum, list)		list_member_ptr(list, datum)
+#define intMember(datum, list)		list_member_int(list, datum)
+#define oidMember(datum, list)		list_member_oid(list, datum)
+
+/*
+ * Note that the old lremove() determined equality via pointer
+ * comparison, whereas the new list_delete() uses equal(); in order to
+ * keep the same behavior, we therefore need to map lremove() calls to
+ * list_delete_ptr() rather than list_delete()
+ */
+#define lremove(elem, list)			list_delete_ptr(list, elem)
+#define LispRemove(elem, list)		list_delete(list, elem)
+#define lremovei(elem, list)		list_delete_int(list, elem)
+#define lremoveo(elem, list)		list_delete_oid(list, elem)
+
+#define ltruncate(n, list)			list_truncate(list, n)
+
+#define set_union(l1, l2)			list_union(l1, l2)
+#define set_uniono(l1, l2)			list_union_oid(l1, l2)
+#define set_ptrUnion(l1, l2)		list_union_ptr(l1, l2)
+
+#define set_difference(l1, l2)		list_difference(l1, l2)
+#define set_differenceo(l1, l2)		list_difference_oid(l1, l2)
+#define set_ptrDifference(l1, l2)	list_difference_ptr(l1, l2)
+
+#define equali(l1, l2)				equal(l1, l2)
+#define equalo(l1, l2)				equal(l1, l2)
+
+#define freeList(list)				list_free(list)
+
+#define listCopy(list)				list_copy(list)
+
+extern int length(List *list);
+
+#endif
+
+/*
+ * Temporary hack: we define the FastList type whether the
+ * compatibility API is enabled or not, since this allows files that
+ * don't use the compatibility API to include headers that reference
+ * the FastList type without an error.
  */
 typedef struct FastList
 {
-	List	   *head;
-	List	   *tail;
+	List		*list;
 } FastList;
 
-#define FastListInit(fl)	( (fl)->head = (fl)->tail = NIL )
-#define FastListFromList(fl, l)  \
-	( (fl)->head = (l), (fl)->tail = llastnode((fl)->head) )
-#define FastListValue(fl)	( (fl)->head )
+#ifdef ENABLE_LIST_COMPAT
 
-#define makeFastList1(fl, x1)  \
-	( (fl)->head = (fl)->tail = makeList1(x1) )
-
-extern List *lcons(void *datum, List *list);
-extern List *lconsi(int datum, List *list);
-extern List *lconso(Oid datum, List *list);
-extern List *lappend(List *list, void *datum);
-extern List *lappendi(List *list, int datum);
-extern List *lappendo(List *list, Oid datum);
-extern List *nconc(List *list1, List *list2);
+extern void FastListInit(FastList *fl);
+extern void FastListFromList(FastList *fl, List *list);
+extern List *FastListValue(FastList *fl);
+extern void makeFastList1(FastList *fl, void *elem);
 extern void FastAppend(FastList *fl, void *datum);
 extern void FastAppendi(FastList *fl, int datum);
 extern void FastAppendo(FastList *fl, Oid datum);
 extern void FastConc(FastList *fl, List *cells);
-extern void FastConcFast(FastList *fl, FastList *fl2);
-extern void *nth(int n, List *l);
-extern int	length(List *list);
-extern void *llast(List *list);
-extern List *llastnode(List *list);
-extern bool member(void *datum, List *list);
-extern bool ptrMember(void *datum, List *list);
-extern bool intMember(int datum, List *list);
-extern bool oidMember(Oid datum, List *list);
-extern List *lremove(void *elem, List *list);
-extern List *LispRemove(void *elem, List *list);
-extern List *lremovei(int elem, List *list);
-extern List *ltruncate(int n, List *list);
-
-extern List *set_union(List *list1, List *list2);
-extern List *set_uniono(List *list1, List *list2);
-extern List *set_ptrUnion(List *list1, List *list2);
-extern List *set_difference(List *list1, List *list2);
-extern List *set_differenceo(List *list1, List *list2);
-extern List *set_ptrDifference(List *list1, List *list2);
-
-extern bool equali(List *list1, List *list2);
-extern bool equalo(List *list1, List *list2);
-
-extern void freeList(List *list);
-
-/* in copyfuncs.c */
-extern List *listCopy(List *list);
+extern void FastConcFast(FastList *fl1, FastList *fl2);
+
+#endif
 
 #endif   /* PG_LIST_H */
diff --git a/src/include/parser/parsetree.h b/src/include/parser/parsetree.h
index 74427f23adbf37876af1d1d3df3c28e5cb159478..9b488c397ac7c625e9583de2b110de73b04e023a 100644
--- a/src/include/parser/parsetree.h
+++ b/src/include/parser/parsetree.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/parser/parsetree.h,v 1.23 2003/11/29 22:41:09 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parsetree.h,v 1.24 2004/05/26 04:41:46 neilc Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,7 +16,7 @@
 #define PARSETREE_H
 
 #include "nodes/parsenodes.h"
-#include "nodes/pg_list.h"		/* for nth(), etc */
+#include "nodes/pg_list.h"		/* for list_nth(), etc */
 
 
 /* ----------------
@@ -30,7 +30,7 @@
  * NB: this will crash and burn if handed an out-of-range RT index
  */
 #define rt_fetch(rangetable_index, rangetable) \
-	((RangeTblEntry *) nth((rangetable_index)-1, rangetable))
+	((RangeTblEntry *) list_nth(rangetable, (rangetable_index)-1))
 
 /*
  *		getrelid
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index 3a90b4648518aa2b25d43297869d0000964a92ac..b9bb7f65ab4db2be29686ee939d17df4d5f27c04 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -3,7 +3,7 @@
  *			  procedural language
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.100 2004/05/10 22:44:49 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.101 2004/05/26 04:41:48 neilc Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -3799,7 +3799,7 @@ exec_simple_check_node(Node *node)
 		case T_List:
 			{
 				List	   *expr = (List *) node;
-				List	   *l;
+				ListCell   *l;
 
 				foreach(l, expr)
 				{
@@ -3838,7 +3838,7 @@ exec_simple_check_plan(PLpgSQL_expr * expr)
 	if (length(spi_plan->ptlist) != 1)
 		return;
 
-	plan = (Plan *) lfirst(spi_plan->ptlist);
+	plan = (Plan *) linitial(spi_plan->ptlist);
 
 	/*
 	 * 2. It must be a RESULT plan --> no scan's required
@@ -3865,7 +3865,7 @@ exec_simple_check_plan(PLpgSQL_expr * expr)
 	if (length(plan->targetlist) != 1)
 		return;
 
-	tle = (TargetEntry *) lfirst(plan->targetlist);
+	tle = (TargetEntry *) linitial(plan->targetlist);
 
 	/*
 	 * 5. Check that all the nodes in the expression are non-scary.
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index d9382aff83bd73ca423edd2f756075dce333f8fd..d30d3cd7c20bbc8a7d803836f50f3a6f2154ccbd 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -31,7 +31,7 @@
  *	  ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.83 2004/04/01 21:28:46 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/pl/tcl/pltcl.c,v 1.84 2004/05/26 04:41:50 neilc Exp $
  *
  **********************************************************************/
 
@@ -1847,7 +1847,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
 	{
 		char		   *argcopy;
 		List		   *names = NIL;
-		List		   *lp;
+		ListCell	   *l;
 		TypeName	   *typename;
 
 		/************************************************************
@@ -1858,8 +1858,8 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
 		argcopy  = pstrdup(args[i]);
 		SplitIdentifierString(argcopy, '.', &names);
 		typename = makeNode(TypeName);
-		foreach (lp, names)
-			typename->names = lappend(typename->names, makeString(lfirst(lp)));
+		foreach (l, names)
+			typename->names = lappend(typename->names, makeString(lfirst(l)));
 
 		typeTup = typenameType(typename);
 		qdesc->argtypes[i] = HeapTupleGetOid(typeTup);