diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index d0ba69009e9051487abcfe358cdf744354d6e26e..1c081f03b04045cd8bc95ef3c0a46a969a1790f7 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.160 2004/05/30 23:40:28 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.161 2004/06/01 04:47:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -237,7 +237,7 @@ create_index_paths(Query *root, RelOptInfo *rel)
 static List *
 group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index)
 {
-	FastList	clausegroup_list;
+	List	   *clausegroup_list = NIL;
 	List	   *restrictinfo_list = rel->baserestrictinfo;
 	int			indexcol = 0;
 	Oid		   *classes = index->classlist;
@@ -245,14 +245,12 @@ group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index)
 	if (restrictinfo_list == NIL)
 		return NIL;
 
-	FastListInit(&clausegroup_list);
 	do
 	{
 		Oid			curClass = classes[0];
-		FastList	clausegroup;
+		List	   *clausegroup = NIL;
 		ListCell   *l;
 
-		FastListInit(&clausegroup);
 		foreach(l, restrictinfo_list)
 		{
 			RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
@@ -262,24 +260,24 @@ group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index)
 										 indexcol,
 										 curClass,
 										 rinfo))
-				FastAppend(&clausegroup, rinfo);
+				clausegroup = lappend(clausegroup, rinfo);
 		}
 
 		/*
 		 * If no clauses match this key, we're done; we don't want to look
 		 * at keys to its right.
 		 */
-		if (FastListValue(&clausegroup) == NIL)
+		if (clausegroup == NIL)
 			break;
 
-		FastAppend(&clausegroup_list, FastListValue(&clausegroup));
+		clausegroup_list = lappend(clausegroup_list, clausegroup);
 
 		indexcol++;
 		classes++;
 
 	} while (!DoneMatchingIndexKeys(classes));
 
-	return FastListValue(&clausegroup_list);
+	return clausegroup_list;
 }
 
 /*
@@ -301,21 +299,18 @@ group_clauses_by_indexkey_for_join(Query *root,
 								   Relids outer_relids,
 								   JoinType jointype, bool isouterjoin)
 {
-	FastList	clausegroup_list;
+	List	   *clausegroup_list = NIL;
 	bool		jfound = false;
 	int			indexcol = 0;
 	Oid		   *classes = index->classlist;
 
-	FastListInit(&clausegroup_list);
 	do
 	{
 		Oid			curClass = classes[0];
-		FastList	clausegroup;
+		List	   *clausegroup = NIL;
 		int			numsources;
 		ListCell   *l;
 
-		FastListInit(&clausegroup);
-
 		/*
 		 * We can always use plain restriction clauses for the rel.  We scan
 		 * these first because we want them first in the clausegroup list
@@ -337,11 +332,11 @@ group_clauses_by_indexkey_for_join(Query *root,
 										 indexcol,
 										 curClass,
 										 rinfo))
-				FastAppend(&clausegroup, rinfo);
+				clausegroup = lappend(clausegroup, rinfo);
 		}
 
 		/* found anything in base restrict list? */
-		numsources = (FastListValue(&clausegroup) != NIL) ? 1 : 0;
+		numsources = (clausegroup != NIL) ? 1 : 0;
 
 		/* Look for joinclauses that are usable with given outer_relids */
 		foreach(l, rel->joininfo)
@@ -367,7 +362,7 @@ group_clauses_by_indexkey_for_join(Query *root,
 												  curClass,
 												  rinfo))
 				{
-					FastAppend(&clausegroup, rinfo);
+					clausegroup = lappend(clausegroup, rinfo);
 					if (!jfoundhere)
 					{
 						jfoundhere = true;
@@ -384,22 +379,19 @@ group_clauses_by_indexkey_for_join(Query *root,
 		 */
 		if (numsources > 1)
 		{
-			List	   *nl;
-
-			nl = remove_redundant_join_clauses(root,
-											 FastListValue(&clausegroup),
-											   jointype);
-			FastListFromList(&clausegroup, nl);
+			clausegroup = remove_redundant_join_clauses(root,
+														clausegroup,
+														jointype);
 		}
 
 		/*
 		 * If no clauses match this key, we're done; we don't want to look
 		 * at keys to its right.
 		 */
-		if (FastListValue(&clausegroup) == NIL)
+		if (clausegroup == NIL)
 			break;
 
-		FastAppend(&clausegroup_list, FastListValue(&clausegroup));
+		clausegroup_list = lappend(clausegroup_list, clausegroup);
 
 		indexcol++;
 		classes++;
@@ -410,7 +402,7 @@ group_clauses_by_indexkey_for_join(Query *root,
 	if (!jfound)
 		return NIL;
 
-	return FastListValue(&clausegroup_list);
+	return clausegroup_list;
 }
 
 
@@ -438,20 +430,17 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel,
 								 IndexOptInfo *index,
 								 Expr *orsubclause)
 {
-	FastList	clausegroup_list;
+	List	   *clausegroup_list = NIL;
 	bool		matched = false;
 	int			indexcol = 0;
 	Oid		   *classes = index->classlist;
 
-	FastListInit(&clausegroup_list);
 	do
 	{
 		Oid			curClass = classes[0];
-		FastList	clausegroup;
+		List	   *clausegroup = NIL;
 		ListCell   *item;
 
-		FastListInit(&clausegroup);
-
 		/* Try to match the OR subclause to the index key */
 		if (IsA(orsubclause, RestrictInfo))
 		{
@@ -459,7 +448,7 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel,
 										 indexcol, curClass,
 										 (RestrictInfo *) orsubclause))
 			{
-				FastAppend(&clausegroup, orsubclause);
+				clausegroup = lappend(clausegroup, orsubclause);
 				matched = true;
 			}
 		}
@@ -474,7 +463,7 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel,
 											 indexcol, curClass,
 											 subsubclause))
 				{
-					FastAppend(&clausegroup, subsubclause);
+					clausegroup = lappend(clausegroup, subsubclause);
 					matched = true;
 				}
 			}
@@ -487,7 +476,7 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel,
 		 * XXX should we always search the top-level list?  Slower but
 		 * could sometimes yield a better plan.
 		 */
-		if (FastListValue(&clausegroup) == NIL)
+		if (clausegroup == NIL)
 		{
 			foreach(item, rel->baserestrictinfo)
 			{
@@ -496,7 +485,7 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel,
 				if (match_clause_to_indexcol(rel, index,
 											 indexcol, curClass,
 											 rinfo))
-					FastAppend(&clausegroup, rinfo);
+					clausegroup = lappend(clausegroup, rinfo);
 			}
 		}
 
@@ -504,10 +493,10 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel,
 		 * If still no clauses match this key, we're done; we don't want
 		 * to look at keys to its right.
 		 */
-		if (FastListValue(&clausegroup) == NIL)
+		if (clausegroup == NIL)
 			break;
 
-		FastAppend(&clausegroup_list, FastListValue(&clausegroup));
+		clausegroup_list = lappend(clausegroup_list, clausegroup);
 
 		indexcol++;
 		classes++;
@@ -517,7 +506,7 @@ group_clauses_by_indexkey_for_or(RelOptInfo *rel,
 	if (!matched)
 		return NIL;
 
-	return FastListValue(&clausegroup_list);
+	return clausegroup_list;
 }
 
 
@@ -2011,14 +2000,13 @@ match_special_index_operator(Expr *clause, Oid opclass,
 List *
 expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
 {
-	FastList	resultquals;
+	List	   *resultquals = NIL;
 	ListCell   *clausegroup_item;
 	Oid		   *classes = index->classlist;
 
 	if (clausegroups == NIL)
 		return NIL;
 
-	FastListInit(&resultquals);
 	clausegroup_item = list_head(clausegroups);
 	do
 	{
@@ -2029,17 +2017,18 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
 		{
 			RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
 
-			FastConc(&resultquals,
-					 expand_indexqual_condition(rinfo, curClass));
+			resultquals = list_concat(resultquals,
+									  expand_indexqual_condition(rinfo,
+																 curClass));
 		}
 
 		clausegroup_item = lnext(clausegroup_item);
 		classes++;
 	} while (clausegroup_item != NULL && !DoneMatchingIndexKeys(classes));
 
-	Assert(clausegroup_item == NULL);	/* else more groups than indexkeys... */
+	Assert(clausegroup_item == NULL);	/* else more groups than indexkeys */
 
-	return FastListValue(&resultquals);
+	return resultquals;
 }
 
 /*
diff --git a/src/backend/optimizer/path/orindxpath.c b/src/backend/optimizer/path/orindxpath.c
index 2071054a1a3bb0e7e0ef29a0d031bb5282446540..9373caaae2ae14d1dc2bb8a250933a2fda3241a9 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.59 2004/05/30 23:40:28 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/path/orindxpath.c,v 1.60 2004/06/01 04:47:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -243,20 +243,14 @@ best_or_subclause_indexes(Query *root,
 						  RelOptInfo *rel,
 						  List *subclauses)
 {
-	FastList	infos;
-	FastList	clauses;
-	FastList	quals;
-	Cost		path_startup_cost;
-	Cost		path_total_cost;
+	List	   *infos = NIL;
+	List	   *clauses = NIL;
+	List	   *quals = NIL;
+	Cost		path_startup_cost = 0;
+	Cost		path_total_cost = 0;
 	ListCell   *slist;
 	IndexPath  *pathnode;
 
-	FastListInit(&infos);
-	FastListInit(&clauses);
-	FastListInit(&quals);
-	path_startup_cost = 0;
-	path_total_cost = 0;
-
 	/* Gather info for each OR subclause */
 	foreach(slist, subclauses)
 	{
@@ -273,9 +267,9 @@ best_or_subclause_indexes(Query *root,
 									 &best_startup_cost, &best_total_cost))
 			return NULL;		/* failed to match this subclause */
 
-		FastAppend(&infos, best_indexinfo);
-		FastAppend(&clauses, best_indexclauses);
-		FastAppend(&quals, best_indexquals);
+		infos = lappend(infos, best_indexinfo);
+		clauses = lappend(clauses, best_indexclauses);
+		quals = lappend(quals, best_indexquals);
 		/*
 		 * Path startup_cost is the startup cost for the first index scan only;
 		 * startup costs for later scans will be paid later on, so they just
@@ -303,9 +297,9 @@ best_or_subclause_indexes(Query *root,
 	 */
 	pathnode->path.pathkeys = NIL;
 
-	pathnode->indexinfo = FastListValue(&infos);
-	pathnode->indexclauses = FastListValue(&clauses);
-	pathnode->indexquals = FastListValue(&quals);
+	pathnode->indexinfo = infos;
+	pathnode->indexclauses = clauses;
+	pathnode->indexquals = quals;
 
 	/* It's not an innerjoin path. */
 	pathnode->isjoininner = false;
diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c
index 2f4a512a60c3f8e2c53ed71710109f3458334add..e9b3feeb18bc4c456ed9db4f3a59933f4f6460ab 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.43 2004/05/30 23:40:29 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.44 2004/06/01 04:47:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,12 +22,8 @@
 
 
 static Node *flatten_andors_mutator(Node *node, void *context);
-static void flatten_andors_and_walker(FastList *out_list, List *andlist);
-static void flatten_andors_or_walker(FastList *out_list, List *orlist);
 static List *pull_ands(List *andlist);
-static void pull_ands_walker(FastList *out_list, List *andlist);
 static List *pull_ors(List *orlist);
-static void pull_ors_walker(FastList *out_list, List *orlist);
 static Expr *find_nots(Expr *qual);
 static Expr *push_nots(Expr *qual);
 static Expr *find_duplicate_ors(Expr *qual);
@@ -122,57 +118,55 @@ flatten_andors_mutator(Node *node, void *context)
 
 		if (bexpr->boolop == AND_EXPR)
 		{
-			FastList	out_list;
+			List	   *out_list = NIL;
+			ListCell   *arg;
 
-			FastListInit(&out_list);
-			flatten_andors_and_walker(&out_list, bexpr->args);
-			return (Node *) make_andclause(FastListValue(&out_list));
+			foreach(arg, bexpr->args)
+			{
+				Node	   *subexpr = flatten_andors((Node *) lfirst(arg));
+
+				/*
+				 * Note: we can destructively concat the subexpression's
+				 * arglist because we know the recursive invocation of
+				 * flatten_andors will have built a new arglist not shared
+				 * with any other expr. Otherwise we'd need a list_copy here.
+				 */
+				if (and_clause(subexpr))
+					out_list = list_concat(out_list,
+										   ((BoolExpr *) subexpr)->args);
+				else
+					out_list = lappend(out_list, subexpr);
+			}
+			return (Node *) make_andclause(out_list);
 		}
 		if (bexpr->boolop == OR_EXPR)
 		{
-			FastList	out_list;
+			List	   *out_list = NIL;
+			ListCell   *arg;
 
-			FastListInit(&out_list);
-			flatten_andors_or_walker(&out_list, bexpr->args);
-			return (Node *) make_orclause(FastListValue(&out_list));
+			foreach(arg, bexpr->args)
+			{
+				Node	   *subexpr = flatten_andors((Node *) lfirst(arg));
+
+				/*
+				 * Note: we can destructively concat the subexpression's
+				 * arglist because we know the recursive invocation of
+				 * flatten_andors will have built a new arglist not shared
+				 * with any other expr. Otherwise we'd need a list_copy here.
+				 */
+				if (or_clause(subexpr))
+					out_list = list_concat(out_list,
+										   ((BoolExpr *) subexpr)->args);
+				else
+					out_list = lappend(out_list, subexpr);
+			}
+			return (Node *) make_orclause(out_list);
 		}
 		/* else it's a NOT clause, fall through */
 	}
 	return expression_tree_mutator(node, flatten_andors_mutator, context);
 }
 
-static void
-flatten_andors_and_walker(FastList *out_list, List *andlist)
-{
-	ListCell   *arg;
-
-	foreach(arg, andlist)
-	{
-		Node	   *subexpr = (Node *) lfirst(arg);
-
-		if (and_clause(subexpr))
-			flatten_andors_and_walker(out_list, ((BoolExpr *) subexpr)->args);
-		else
-			FastAppend(out_list, flatten_andors(subexpr));
-	}
-}
-
-static void
-flatten_andors_or_walker(FastList *out_list, List *orlist)
-{
-	ListCell   *arg;
-
-	foreach(arg, orlist)
-	{
-		Node	   *subexpr = (Node *) lfirst(arg);
-
-		if (or_clause(subexpr))
-			flatten_andors_or_walker(out_list, ((BoolExpr *) subexpr)->args);
-		else
-			FastAppend(out_list, flatten_andors(subexpr));
-	}
-}
-
 /*
  * pull_ands
  *	  Recursively flatten nested AND clauses into a single and-clause list.
@@ -183,27 +177,26 @@ flatten_andors_or_walker(FastList *out_list, List *orlist)
 static List *
 pull_ands(List *andlist)
 {
-	FastList	out_list;
-
-	FastListInit(&out_list);
-	pull_ands_walker(&out_list, andlist);
-	return FastListValue(&out_list);
-}
-
-static void
-pull_ands_walker(FastList *out_list, List *andlist)
-{
+	List	   *out_list = NIL;
 	ListCell   *arg;
 
 	foreach(arg, andlist)
 	{
 		Node	   *subexpr = (Node *) lfirst(arg);
 
+		/*
+		 * Note: we can destructively concat the subexpression's arglist
+		 * because we know the recursive invocation of pull_ands will have
+		 * built a new arglist not shared with any other expr. Otherwise
+		 * we'd need a list_copy here.
+		 */
 		if (and_clause(subexpr))
-			pull_ands_walker(out_list, ((BoolExpr *) subexpr)->args);
+			out_list = list_concat(out_list,
+								   pull_ands(((BoolExpr *) subexpr)->args));
 		else
-			FastAppend(out_list, subexpr);
+			out_list = lappend(out_list, subexpr);
 	}
+	return out_list;
 }
 
 /*
@@ -216,27 +209,26 @@ pull_ands_walker(FastList *out_list, List *andlist)
 static List *
 pull_ors(List *orlist)
 {
-	FastList	out_list;
-
-	FastListInit(&out_list);
-	pull_ors_walker(&out_list, orlist);
-	return FastListValue(&out_list);
-}
-
-static void
-pull_ors_walker(FastList *out_list, List *orlist)
-{
+	List	   *out_list = NIL;
 	ListCell   *arg;
 
 	foreach(arg, orlist)
 	{
 		Node	   *subexpr = (Node *) lfirst(arg);
 
+		/*
+		 * Note: we can destructively concat the subexpression's arglist
+		 * because we know the recursive invocation of pull_ors will have
+		 * built a new arglist not shared with any other expr. Otherwise
+		 * we'd need a list_copy here.
+		 */
 		if (or_clause(subexpr))
-			pull_ors_walker(out_list, ((BoolExpr *) subexpr)->args);
+			out_list = list_concat(out_list,
+								   pull_ors(((BoolExpr *) subexpr)->args));
 		else
-			FastAppend(out_list, subexpr);
+			out_list = lappend(out_list, subexpr);
 	}
+	return out_list;
 }
 
 
@@ -257,23 +249,21 @@ find_nots(Expr *qual)
 
 	if (and_clause((Node *) qual))
 	{
-		FastList	t_list;
+		List	   *t_list = NIL;
 		ListCell   *temp;
 
-		FastListInit(&t_list);
 		foreach(temp, ((BoolExpr *) qual)->args)
-			FastAppend(&t_list, find_nots(lfirst(temp)));
-		return make_andclause(pull_ands(FastListValue(&t_list)));
+			t_list = lappend(t_list, find_nots(lfirst(temp)));
+		return make_andclause(pull_ands(t_list));
 	}
 	else if (or_clause((Node *) qual))
 	{
-		FastList	t_list;
+		List	   *t_list = NIL;
 		ListCell   *temp;
 
-		FastListInit(&t_list);
 		foreach(temp, ((BoolExpr *) qual)->args)
-			FastAppend(&t_list, find_nots(lfirst(temp)));
-		return make_orclause(pull_ors(FastListValue(&t_list)));
+			t_list = lappend(t_list, find_nots(lfirst(temp)));
+		return make_orclause(pull_ors(t_list));
 	}
 	else if (not_clause((Node *) qual))
 		return push_nots(get_notclausearg(qual));
@@ -323,23 +313,21 @@ push_nots(Expr *qual)
 		 * i.e., swap AND for OR and negate all the subclauses.
 		 *--------------------
 		 */
-		FastList	t_list;
+		List	   *t_list = NIL;
 		ListCell   *temp;
 
-		FastListInit(&t_list);
 		foreach(temp, ((BoolExpr *) qual)->args)
-			FastAppend(&t_list, push_nots(lfirst(temp)));
-		return make_orclause(pull_ors(FastListValue(&t_list)));
+			t_list = lappend(t_list, push_nots(lfirst(temp)));
+		return make_orclause(pull_ors(t_list));
 	}
 	else if (or_clause((Node *) qual))
 	{
-		FastList	t_list;
+		List	   *t_list = NIL;
 		ListCell   *temp;
 
-		FastListInit(&t_list);
 		foreach(temp, ((BoolExpr *) qual)->args)
-			FastAppend(&t_list, push_nots(lfirst(temp)));
-		return make_andclause(pull_ands(FastListValue(&t_list)));
+			t_list = lappend(t_list, push_nots(lfirst(temp)));
+		return make_andclause(pull_ands(t_list));
 	}
 	else if (not_clause((Node *) qual))
 	{
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index a3389607b6e1b66468bafd14eb4404bd5167524e..bf12320626da0f71875f192ba7710587bf0bd9e2 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.172 2004/05/30 23:40:30 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.173 2004/06/01 04:47:45 tgl Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -846,24 +846,21 @@ is_pseudo_constant_clause_relids(Node *clause, Relids relids)
 List *
 pull_constant_clauses(List *quals, List **constantQual)
 {
-	FastList	constqual,
-				restqual;
+	List	   *constqual = NIL,
+			   *restqual = NIL;
 	ListCell   *q;
 
-	FastListInit(&constqual);
-	FastListInit(&restqual);
-
 	foreach(q, quals)
 	{
 		Node	   *qual = (Node *) lfirst(q);
 
 		if (is_pseudo_constant_clause(qual))
-			FastAppend(&constqual, qual);
+			constqual = lappend(constqual, qual);
 		else
-			FastAppend(&restqual, qual);
+			restqual = lappend(restqual, qual);
 	}
-	*constantQual = FastListValue(&constqual);
-	return FastListValue(&restqual);
+	*constantQual = constqual;
+	return restqual;
 }
 
 
@@ -1411,7 +1408,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 		CaseExpr   *caseexpr = (CaseExpr *) node;
 		CaseExpr   *newcase;
 		Node	   *newarg;
-		FastList	newargs;
+		List	   *newargs;
 		Node	   *defresult;
 		Const	   *const_input;
 		ListCell   *arg;
@@ -1421,7 +1418,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 												active_fns);
 
 		/* Simplify the WHEN clauses */
-		FastListInit(&newargs);
+		newargs = NIL;
 		foreach(arg, caseexpr->args)
 		{
 			/* Simplify this alternative's condition and result */
@@ -1434,7 +1431,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 			if (casewhen->expr == NULL ||
 				!IsA(casewhen->expr, Const))
 			{
-				FastAppend(&newargs, casewhen);
+				newargs = lappend(newargs, casewhen);
 				continue;
 			}
 			const_input = (Const *) casewhen->expr;
@@ -1446,13 +1443,13 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 			 * Found a TRUE condition.	If it's the first (un-dropped)
 			 * alternative, the CASE reduces to just this alternative.
 			 */
-			if (FastListValue(&newargs) == NIL)
+			if (newargs == NIL)
 				return (Node *) casewhen->result;
 
 			/*
 			 * Otherwise, add it to the list, and drop all the rest.
 			 */
-			FastAppend(&newargs, casewhen);
+			newargs = lappend(newargs, casewhen);
 			break;
 		}
 
@@ -1464,13 +1461,13 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 		 * If no non-FALSE alternatives, CASE reduces to the default
 		 * result
 		 */
-		if (FastListValue(&newargs) == NIL)
+		if (newargs == NIL)
 			return defresult;
 		/* Otherwise we need a new CASE node */
 		newcase = makeNode(CaseExpr);
 		newcase->casetype = caseexpr->casetype;
 		newcase->arg = (Expr *) newarg;
-		newcase->args = FastListValue(&newargs);
+		newcase->args = newargs;
 		newcase->defresult = (Expr *) defresult;
 		return (Node *) newcase;
 	}
@@ -1479,10 +1476,10 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 		ArrayExpr  *arrayexpr = (ArrayExpr *) node;
 		ArrayExpr  *newarray;
 		bool		all_const = true;
-		FastList	newelems;
+		List	   *newelems;
 		ListCell   *element;
 
-		FastListInit(&newelems);
+		newelems = NIL;
 		foreach(element, arrayexpr->elements)
 		{
 			Node	   *e;
@@ -1491,13 +1488,13 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 											   active_fns);
 			if (!IsA(e, Const))
 				all_const = false;
-			FastAppend(&newelems, e);
+			newelems = lappend(newelems, e);
 		}
 
 		newarray = makeNode(ArrayExpr);
 		newarray->array_typeid = arrayexpr->array_typeid;
 		newarray->element_typeid = arrayexpr->element_typeid;
-		newarray->elements = FastListValue(&newelems);
+		newarray->elements = newelems;
 		newarray->multidims = arrayexpr->multidims;
 
 		if (all_const)
@@ -1510,10 +1507,10 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 	{
 		CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
 		CoalesceExpr *newcoalesce;
-		FastList	newargs;
+		List	   *newargs;
 		ListCell   *arg;
 
-		FastListInit(&newargs);
+		newargs = NIL;
 		foreach(arg, coalesceexpr->args)
 		{
 			Node	   *e;
@@ -1530,15 +1527,15 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
 			{
 				if (((Const *) e)->constisnull)
 					continue;	/* drop null constant */
-				if (FastListValue(&newargs) == NIL)
+				if (newargs == NIL)
 					return e;	/* first expr */
 			}
-			FastAppend(&newargs, e);
+			newargs = lappend(newargs, e);
 		}
 
 		newcoalesce = makeNode(CoalesceExpr);
 		newcoalesce->coalescetype = coalesceexpr->coalescetype;
-		newcoalesce->args = FastListValue(&newargs);
+		newcoalesce->args = newargs;
 		return (Node *) newcoalesce;
 	}
 	if (IsA(node, FieldSelect))
@@ -2971,16 +2968,17 @@ expression_tree_mutator(Node *node,
 				 * NOTE: this would fail badly on a list with integer
 				 * elements!
 				 */
-				FastList	resultlist;
+				List	   *resultlist;
 				ListCell   *temp;
 
-				FastListInit(&resultlist);
+				resultlist = NIL;
 				foreach(temp, (List *) node)
 				{
-					FastAppend(&resultlist,
-							   mutator((Node *) lfirst(temp), context));
+					resultlist = lappend(resultlist,
+										 mutator((Node *) lfirst(temp),
+												 context));
 				}
-				return (Node *) FastListValue(&resultlist);
+				return (Node *) resultlist;
 			}
 			break;
 		case T_FromExpr:
@@ -3063,7 +3061,7 @@ query_tree_mutator(Query *query,
 				   void *context,
 				   int flags)
 {
-	FastList	newrt;
+	List	   *newrt;
 	ListCell   *rt;
 
 	Assert(query != NULL && IsA(query, Query));
@@ -3083,7 +3081,7 @@ query_tree_mutator(Query *query,
 	MUTATE(query->limitOffset, query->limitOffset, Node *);
 	MUTATE(query->limitCount, query->limitCount, Node *);
 	MUTATE(query->in_info_list, query->in_info_list, List *);
-	FastListInit(&newrt);
+	newrt = NIL;
 	foreach(rt, query->rtable)
 	{
 		RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
@@ -3113,9 +3111,9 @@ query_tree_mutator(Query *query,
 				MUTATE(newrte->funcexpr, rte->funcexpr, Node *);
 				break;
 		}
-		FastAppend(&newrt, newrte);
+		newrt = lappend(newrt, newrte);
 	}
-	query->rtable = FastListValue(&newrt);
+	query->rtable = newrt;
 	return query;
 }
 
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index e7ff6bfbe9d2a112a73165918b1c32c3d22a39c5..a819d08d44792fa2d5daf527491d3f145ed24be0 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.93 2004/05/30 23:40:31 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.94 2004/06/01 04:47:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -192,12 +192,10 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
 	Index		varno = rel->relid;
 	RangeTblEntry *rte = rt_fetch(varno, root->rtable);
 	Relation	relation;
-	FastList	tlist;
+	List	   *tlist = NIL;
 	int			attrno,
 				numattrs;
 
-	FastListInit(&tlist);
-
 	Assert(rte->rtekind == RTE_RELATION);
 
 	relation = heap_open(rte->relid, AccessShareLock);
@@ -211,11 +209,11 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
 		if (att_tup->attisdropped)
 		{
 			/* found a dropped col, so punt */
-			FastListInit(&tlist);
+			tlist = NIL;
 			break;
 		}
 
-		FastAppend(&tlist,
+		tlist = lappend(tlist,
 				   create_tl_element(makeVar(varno,
 											 attrno,
 											 att_tup->atttypid,
@@ -226,7 +224,7 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
 
 	heap_close(relation, AccessShareLock);
 
-	return FastListValue(&tlist);
+	return tlist;
 }
 
 /*
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index cae304f3e09d908df72d6f36e493717d1336c7cc..e46655e17dbd1868d1c941728782ec7959f9a2d9 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.58 2004/05/30 23:40:31 neilc Exp $
+ *	  $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.59 2004/06/01 04:47:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -43,7 +43,7 @@ typedef struct
 
 typedef struct
 {
-	FastList	varlist;
+	List	   *varlist;
 	bool		includeUpperVars;
 } pull_var_clause_context;
 
@@ -446,11 +446,11 @@ pull_var_clause(Node *node, bool includeUpperVars)
 {
 	pull_var_clause_context context;
 
-	FastListInit(&context.varlist);
+	context.varlist = NIL;
 	context.includeUpperVars = includeUpperVars;
 
 	pull_var_clause_walker(node, &context);
-	return FastListValue(&context.varlist);
+	return context.varlist;
 }
 
 static bool
@@ -461,7 +461,7 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
 	if (IsA(node, Var))
 	{
 		if (((Var *) node)->varlevelsup == 0 || context->includeUpperVars)
-			FastAppend(&context->varlist, node);
+			context->varlist = lappend(context->varlist, node);
 		return false;
 	}
 	return expression_tree_walker(node, pull_var_clause_walker,