diff --git a/doc/src/sgml/arch-dev.sgml b/doc/src/sgml/arch-dev.sgml
index 7bc8e8482e11152ded5dc486d3953c4bbb6fcdca..b8d03725bea85e77d8dc485fb0e20899d246e0ac 100644
--- a/doc/src/sgml/arch-dev.sgml
+++ b/doc/src/sgml/arch-dev.sgml
@@ -3758,7 +3758,7 @@ $\ldots$/src/backend/tcop/postgres.c}.
   List *
   pg_parse_and_plan(char *query_string, Oid *typev,
                     int nargs, 
-                    QueryTreeList **queryListP,
+                    List **queryListP,
                     CommandDest dest) 
   {
                             .
@@ -4032,7 +4032,7 @@ instead.
 
     if(IsA(tree, SelectStmt))
     {
-      QueryTreeList *qtree;
+      List *qtrees;
 
       /* If we get to the tree given in first_select 
        * return parsetree instead of performing 
@@ -4044,9 +4044,8 @@ instead.
       else 
       {    
         /* transform the unprocessed Query nodes */ 
-        qtree = 
-             parse_analyze(lcons(tree, NIL), NULL);
-        result = (Node *)qtree->qtrees[0];      
+        qtrees = parse_analyze(lcons(tree, NIL), NULL);
+        result = (Node *) lfirst(qtrees);
       }      
     }  
     if(IsA(tree,Expr))
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 0caf676bd0f584f63af083402159a8c75cfb7042..71ae1ebf8139b8ffc108b9977f70802440df8916 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.79 1999/05/10 04:02:03 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.80 1999/05/13 07:28:26 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1498,9 +1498,9 @@ StoreAttrDefault(Relation rel, AttrDefault *attrdef)
 	char		str[MAX_PARSE_BUFFER];
 	char		cast[2 * NAMEDATALEN] = {0};
 	Form_pg_attribute atp = rel->rd_att->attrs[attrdef->adnum - 1];
-	QueryTreeList *queryTree_list;
-	Query	   *query;
+	List	   *queryTree_list;
 	List	   *planTree_list;
+	Query	   *query;
 	TargetEntry *te;
 	Resdom	   *resdom;
 	Node	   *expr;
@@ -1522,9 +1522,10 @@ start:;
 			 "select %s%s from \"%.*s\"", attrdef->adsrc, cast,
 			 NAMEDATALEN, rel->rd_rel->relname.data);
 	setheapoverride(true);
-	planTree_list = (List *) pg_parse_and_plan(str, NULL, 0, &queryTree_list, None, FALSE);
+	planTree_list = pg_parse_and_plan(str, NULL, 0,
+									  &queryTree_list, None, FALSE);
 	setheapoverride(false);
-	query = (Query *) (queryTree_list->qtrees[0]);
+	query = (Query *) lfirst(queryTree_list);
 
 	if (length(query->rtable) > 1 ||
 		flatten_tlist(query->targetList) != NIL)
@@ -1582,9 +1583,9 @@ static void
 StoreRelCheck(Relation rel, ConstrCheck *check)
 {
 	char		str[MAX_PARSE_BUFFER];
-	QueryTreeList *queryTree_list;
-	Query	   *query;
+	List	   *queryTree_list;
 	List	   *planTree_list;
+	Query	   *query;
 	Plan	   *plan;
 	List	   *qual;
 	char	   *ccbin;
@@ -1603,9 +1604,10 @@ StoreRelCheck(Relation rel, ConstrCheck *check)
 			"select 1 from \"%.*s\" where %s",
 			NAMEDATALEN, rel->rd_rel->relname.data, check->ccsrc);
 	setheapoverride(true);
-	planTree_list = (List *) pg_parse_and_plan(str, NULL, 0, &queryTree_list, None, FALSE);
+	planTree_list = pg_parse_and_plan(str, NULL, 0,
+									  &queryTree_list, None, FALSE);
 	setheapoverride(false);
-	query = (Query *) (queryTree_list->qtrees[0]);
+	query = (Query *) lfirst(queryTree_list);
 
 	if (length(query->rtable) > 1)
 		elog(ERROR, "Only relation '%.*s' can be referenced",
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 90c41f57ee8a73ec206e60e6ca79fdd2d8b0531f..7c22ce007cd086095c584b0ad5bfbe3f46034ac3 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.27 1999/04/18 02:57:22 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.28 1999/05/13 07:28:27 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -67,7 +67,7 @@ ProcedureCreate(char *procedureName,
 	Oid			languageObjectId;
 	Oid			typeObjectId;
 	List	   *x;
-	QueryTreeList *querytree_list;
+	List	   *querytree_list;
 	List	   *plan_list;
 	Oid			typev[8];
 	Oid			relid;
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 1cb57d5651e7c2fb53805dfa4b729734d391e511..f9b729b8386ff2a3dfc9176a3f1af2bc07067fcb 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.24 1999/02/13 23:15:20 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.25 1999/05/13 07:28:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -97,26 +97,23 @@ init_execution_state(FunctionCachePtr fcache,
 	execution_state *newes;
 	execution_state *nextes;
 	execution_state *preves;
-	QueryTreeList *queryTree_list;
-	int			i;
-	List	   *planTree_list;
-	int			nargs;
-
-	nargs = fcache->nargs;
+	List	   *queryTree_list,
+			   *planTree_list,
+			   *qtl_item;
+	int			nargs = fcache->nargs;
 
 	newes = (execution_state *) palloc(sizeof(execution_state));
 	nextes = newes;
 	preves = (execution_state *) NULL;
 
+	planTree_list = pg_parse_and_plan(fcache->src, fcache->argOidVect,
+									  nargs, &queryTree_list, None, FALSE);
 
-	planTree_list = (List *)
-		pg_parse_and_plan(fcache->src, fcache->argOidVect, nargs, &queryTree_list, None, FALSE);
-
-	for (i = 0; i < queryTree_list->len; i++)
+	foreach (qtl_item, queryTree_list)
 	{
-		EState	   *estate;
-		Query	   *queryTree = (Query *) (queryTree_list->qtrees[i]);
+		Query	   *queryTree = lfirst(qtl_item);
 		Plan	   *planTree = lfirst(planTree_list);
+		EState	   *estate;
 
 		if (!nextes)
 			nextes = (execution_state *) palloc(sizeof(execution_state));
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index d3064128a4373ed80597f9ab37c810d03a97d974..f6e5b8c585e260283a7a4819a288711963ba32e2 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -3,7 +3,7 @@
  * spi.c
  *				Server Programming Interface
  *
- * $Id: spi.c,v 1.36 1999/03/30 01:37:23 momjian Exp $
+ * $Id: spi.c,v 1.37 1999/05/13 07:28:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -602,18 +602,18 @@ spi_printtup(HeapTuple tuple, TupleDesc tupdesc, DestReceiver* self)
 static int
 _SPI_execute(char *src, int tcount, _SPI_plan *plan)
 {
-	QueryTreeList *queryTree_list;
+	List	   *queryTree_list;
 	List	   *planTree_list;
+	List	   *queryTree_list_item;
 	List	   *ptlist;
 	QueryDesc  *qdesc;
 	Query	   *queryTree;
 	Plan	   *planTree;
 	EState	   *state;
-	int			qlen;
 	int			nargs = 0;
 	Oid		   *argtypes = NULL;
-	int			res;
-	int			i;
+	int			res = 0;
+	bool		islastquery;
 
 	/* Increment CommandCounter to see changes made by now */
 	CommandCounterIncrement();
@@ -628,18 +628,17 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
 		nargs = plan->nargs;
 		argtypes = plan->argtypes;
 	}
-	ptlist = planTree_list = (List *)
+	ptlist = planTree_list =
 		pg_parse_and_plan(src, argtypes, nargs, &queryTree_list, None, FALSE);
 
 	_SPI_current->qtlist = queryTree_list;
 
-	qlen = queryTree_list->len;
-	for (i = 0;; i++)
+	foreach (queryTree_list_item, queryTree_list)
 	{
-		queryTree = (Query *) (queryTree_list->qtrees[i]);
+		queryTree = (Query *) lfirst(queryTree_list_item);
 		planTree = lfirst(planTree_list);
-
 		planTree_list = lnext(planTree_list);
+		islastquery = (planTree_list == NIL); /* assume lists are same len */
 
 		if (queryTree->commandType == CMD_UTILITY)
 		{
@@ -659,32 +658,32 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
 			if (plan == NULL)
 			{
 				ProcessUtility(queryTree->utilityStmt, None);
-				if (i < qlen - 1)
+				if (! islastquery)
 					CommandCounterIncrement();
 				else
 					return res;
 			}
-			else if (i >= qlen - 1)
+			else if (islastquery)
 				break;
 		}
 		else if (plan == NULL)
 		{
 			qdesc = CreateQueryDesc(queryTree, planTree,
-									(i < qlen - 1) ? None : SPI);
+									islastquery ? SPI : None);
 			state = CreateExecutorState();
-			res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount);
-			if (res < 0 || i >= qlen - 1)
+			res = _SPI_pquery(qdesc, state, islastquery ? tcount : 0);
+			if (res < 0 || islastquery)
 				return res;
 			CommandCounterIncrement();
 		}
 		else
 		{
 			qdesc = CreateQueryDesc(queryTree, planTree,
-									(i < qlen - 1) ? None : SPI);
-			res = _SPI_pquery(qdesc, NULL, (i < qlen - 1) ? 0 : tcount);
+									islastquery ? SPI : None);
+			res = _SPI_pquery(qdesc, NULL, islastquery ? tcount : 0);
 			if (res < 0)
 				return res;
-			if (i >= qlen - 1)
+			if (islastquery)
 				break;
 		}
 	}
@@ -693,23 +692,22 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
 	plan->ptlist = ptlist;
 
 	return res;
-
 }
 
 static int
 _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
 {
-	QueryTreeList *queryTree_list = plan->qtlist;
+	List	   *queryTree_list = plan->qtlist;
 	List	   *planTree_list = plan->ptlist;
+	List	   *queryTree_list_item;
 	QueryDesc  *qdesc;
 	Query	   *queryTree;
 	Plan	   *planTree;
 	EState	   *state;
 	int			nargs = plan->nargs;
-	int			qlen = queryTree_list->len;
-	int			res;
-	int			i,
-				k;
+	int			res = 0;
+	bool		islastquery;
+	int			k;
 
 	/* Increment CommandCounter to see changes made by now */
 	CommandCounterIncrement();
@@ -719,17 +717,17 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
 	_SPI_current->tuptable = NULL;
 	_SPI_current->qtlist = NULL;
 
-	for (i = 0;; i++)
+	foreach (queryTree_list_item, queryTree_list)
 	{
-		queryTree = (Query *) (queryTree_list->qtrees[i]);
+		queryTree = (Query *) lfirst(queryTree_list_item);
 		planTree = lfirst(planTree_list);
-
 		planTree_list = lnext(planTree_list);
+		islastquery = (planTree_list == NIL); /* assume lists are same len */
 
 		if (queryTree->commandType == CMD_UTILITY)
 		{
 			ProcessUtility(queryTree->utilityStmt, None);
-			if (i < qlen - 1)
+			if (! islastquery)
 				CommandCounterIncrement();
 			else
 				return SPI_OK_UTILITY;
@@ -737,7 +735,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
 		else
 		{
 			qdesc = CreateQueryDesc(queryTree, planTree,
-									(i < qlen - 1) ? None : SPI);
+									islastquery ? SPI : None);
 			state = CreateExecutorState();
 			if (nargs > 0)
 			{
@@ -756,15 +754,14 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
 			}
 			else
 				state->es_param_list_info = NULL;
-			res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount);
-			if (res < 0 || i >= qlen - 1)
+			res = _SPI_pquery(qdesc, state, islastquery ? tcount : 0);
+			if (res < 0 || islastquery)
 				return res;
 			CommandCounterIncrement();
 		}
 	}
 
 	return res;
-
 }
 
 static int
@@ -955,12 +952,7 @@ _SPI_end_call(bool procmem)
 	 */
 	_SPI_curid--;
 
-	if (_SPI_current->qtlist)	/* free _SPI_plan allocations */
-	{
-		free(_SPI_current->qtlist->qtrees);
-		free(_SPI_current->qtlist);
-		_SPI_current->qtlist = NULL;
-	}
+	_SPI_current->qtlist = NULL;
 
 	if (procmem)				/* switch to the procedure memory context */
 	{							/* but free Executor memory before */
@@ -1000,7 +992,6 @@ _SPI_copy_plan(_SPI_plan *plan, int location)
 {
 	_SPI_plan  *newplan;
 	MemoryContext oldcxt = NULL;
-	int			i;
 
 	if (location == _SPI_CPLAN_PROCXT)
 		oldcxt = MemoryContextSwitchTo((MemoryContext)
@@ -1009,14 +1000,7 @@ _SPI_copy_plan(_SPI_plan *plan, int location)
 		oldcxt = MemoryContextSwitchTo(TopMemoryContext);
 
 	newplan = (_SPI_plan *) palloc(sizeof(_SPI_plan));
-	newplan->qtlist = (QueryTreeList *) palloc(sizeof(QueryTreeList));
-	newplan->qtlist->len = plan->qtlist->len;
-	newplan->qtlist->qtrees = (Query **) palloc(plan->qtlist->len *
-												sizeof(Query *));
-	for (i = 0; i < plan->qtlist->len; i++)
-		newplan->qtlist->qtrees[i] = (Query *)
-			copyObject(plan->qtlist->qtrees[i]);
-
+	newplan->qtlist = (List *) copyObject(plan->qtlist);
 	newplan->ptlist = (List *) copyObject(plan->ptlist);
 	newplan->nargs = plan->nargs;
 	if (plan->nargs > 0)
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index a55d444a8b3114a98949b759dc1436b660347910..d68a44e0c275d5d72600d648dc2d0878ac276b4a 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.51 1999/05/12 15:01:37 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.52 1999/05/13 07:28:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -671,7 +671,7 @@ make_sortplan(List *tlist, List *sortcls, Plan *plannode)
  * XXX Why is this function in this module?
  */
 void
-pg_checkretval(Oid rettype, QueryTreeList *queryTreeList)
+pg_checkretval(Oid rettype, List *queryTreeList)
 {
 	Query	   *parse;
 	List	   *tlist;
@@ -686,7 +686,7 @@ pg_checkretval(Oid rettype, QueryTreeList *queryTreeList)
 	int			i;
 
 	/* find the final query */
-	parse = queryTreeList->qtrees[queryTreeList->len - 1];
+	parse = (Query *) nth(length(queryTreeList)-1, queryTreeList);
 
 	/*
 	 * test 1:	if the last query is a utility invocation, then there had
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 2384c70c9f49da727d65cdf356237fffce615ea5..98c5748868432d17fc231a8569940be2e843430f 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- *  $Id: analyze.c,v 1.102 1999/05/12 07:17:18 thomas Exp $
+ *  $Id: analyze.c,v 1.103 1999/05/13 07:28:34 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -59,17 +59,12 @@ List	   *extras_after = NIL;
  * all transformed to Query while the rest stays the same.
  *
  */
-QueryTreeList *
+List *
 parse_analyze(List *pl, ParseState *parentParseState)
 {
-	QueryTreeList *result;
+	List *result = NIL;
 	ParseState *pstate;
 	Query *parsetree;
-	int			i = 0;
-
-	result = malloc(sizeof(QueryTreeList));
-	result->len = length(pl);
-	result->qtrees = (Query **) malloc(result->len * sizeof(Query *));
 
 	while (pl != NIL)
 	{
@@ -78,35 +73,25 @@ parse_analyze(List *pl, ParseState *parentParseState)
 		if (pstate->p_target_relation != NULL)
 			heap_close(pstate->p_target_relation);
 
-		if (extras_before != NIL)
+		while (extras_before != NIL)
 		{
-			result->len += length(extras_before);
-			result->qtrees = (Query **) realloc(result->qtrees, result->len * sizeof(Query *));
-			while (extras_before != NIL)
-			{
-				result->qtrees[i++] = transformStmt(pstate, lfirst(extras_before));
-				if (pstate->p_target_relation != NULL)
-					heap_close(pstate->p_target_relation);
-				extras_before = lnext(extras_before);
-			}
+			result = lappend(result,
+							 transformStmt(pstate, lfirst(extras_before)));
+			if (pstate->p_target_relation != NULL)
+				heap_close(pstate->p_target_relation);
+			extras_before = lnext(extras_before);
 		}
-		extras_before = NIL;
 
-		result->qtrees[i++] = parsetree;
+		result = lappend(result, parsetree);
 
-		if (extras_after != NIL)
+		while (extras_after != NIL)
 		{
-			result->len += length(extras_after);
-			result->qtrees = (Query **) realloc(result->qtrees, result->len * sizeof(Query *));
-			while (extras_after != NIL)
-			{
-				result->qtrees[i++] = transformStmt(pstate, lfirst(extras_after));
-				if (pstate->p_target_relation != NULL)
-					heap_close(pstate->p_target_relation);
-				extras_after = lnext(extras_after);
-			}
+			result = lappend(result,
+							 transformStmt(pstate, lfirst(extras_after)));
+			if (pstate->p_target_relation != NULL)
+				heap_close(pstate->p_target_relation);
+			extras_after = lnext(extras_after);
 		}
-		extras_after = NIL;
 
 		pl = lnext(pl);
 		pfree(pstate);
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 61359e3452a68a0bc3240a415c6bf671283b489d..ceabc549a3d903359c142db22aca710fe561b23e 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.30 1999/05/12 15:01:50 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.31 1999/05/13 07:28:36 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -752,23 +752,24 @@ List *
 transformUnionClause(List *unionClause, List *targetlist)
 {
 	List	   *union_list = NIL;
-	QueryTreeList *qlist;
-	int			i;
+	List	   *qlist,
+			   *qlist_item;
 
 	if (unionClause)
 	{
 		/* recursion */
 		qlist = parse_analyze(unionClause, NULL);
 
-		for (i = 0; i < qlist->len; i++)
+		foreach (qlist_item, qlist)
 		{
+			Query	   *query = (Query *) lfirst(qlist_item);
 			List	   *prev_target = targetlist;
 			List	   *next_target;
 
-			if (length(targetlist) != length(qlist->qtrees[i]->targetList))
+			if (length(targetlist) != length(query->targetList))
 				elog(ERROR, "Each UNION clause must have the same number of columns");
 
-			foreach(next_target, qlist->qtrees[i]->targetList)
+			foreach(next_target, query->targetList)
 			{
 				Oid			itype;
 				Oid			otype;
@@ -819,7 +820,7 @@ transformUnionClause(List *unionClause, List *targetlist)
 				}
 				prev_target = lnext(prev_target);
 			}
-			union_list = lappend(union_list, qlist->qtrees[i]);
+			union_list = lappend(union_list, query);
 		}
 		return union_list;
 	}
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 24b1e1b91d2b25bbcc92fa38e0f052ca717ec23c..91bba7fc2770121505113bee2bf92f1729c11502 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.44 1999/05/12 07:14:24 thomas Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.45 1999/05/13 07:28:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -274,16 +274,19 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
 		case T_SubLink:
 			{
 				SubLink    *sublink = (SubLink *) expr;
-				QueryTreeList *qtree;
+				List	   *qtrees;
+				Query	   *qtree;
 				List	   *llist;
 
 				pstate->p_hasSubLinks = true;
-				qtree = parse_analyze(lcons(sublink->subselect, NIL), pstate);
-				if (qtree->len != 1 ||
-					qtree->qtrees[0]->commandType != CMD_SELECT ||
-					qtree->qtrees[0]->resultRelation != 0)
+				qtrees = parse_analyze(lcons(sublink->subselect, NIL), pstate);
+				if (length(qtrees) != 1)
 					elog(ERROR, "parser: bad query in subselect");
-				sublink->subselect = (Node *) qtree->qtrees[0];
+				qtree = (Query *) lfirst(qtrees);
+				if (qtree->commandType != CMD_SELECT ||
+					qtree->resultRelation != 0)
+					elog(ERROR, "parser: bad query in subselect");
+				sublink->subselect = (Node *) qtree;
 
 				if (sublink->subLinkType != EXISTS_SUBLINK)
 				{
diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c
index 5361be4ca19ca1ed64f41d33ed495be803dd442d..b1059936413dde7e231c14c81a858eefe21c2daa 100644
--- a/src/backend/parser/parser.c
+++ b/src/backend/parser/parser.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.37 1999/02/13 23:17:10 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.38 1999/05/13 07:28:39 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,34 +20,32 @@
 #include "parser/parse_node.h"
 #include "parser/parser.h"
 
+#if defined(FLEX_SCANNER)
+extern void DeleteBuffer(void);
+#endif	 /* FLEX_SCANNER */
+
 char	   *parseString;		/* the char* which holds the string to be
 								 * parsed */
-List	   *parsetree = NIL;
+List	   *parsetree;			/* result of parsing is left here */
 
 #ifdef SETS_FIXED
 static void fixupsets();
 static void define_sets();
-
 #endif
+
 /*
  * parser-- returns a list of parse trees
- *
- *	CALLER is responsible for free'ing the list returned
  */
-QueryTreeList *
+List *
 parser(char *str, Oid *typev, int nargs)
 {
-	QueryTreeList *queryList;
+	List	   *queryList;
 	int			yyresult;
 
-#if defined(FLEX_SCANNER)
-	extern void DeleteBuffer(void);
-
-#endif	 /* FLEX_SCANNER */
-
 	init_io();
 
 	parseString = pstrdup(str);
+	parsetree = NIL;			/* in case parser forgets to set it */
 
 	parser_init(typev, nargs);
 	yyresult = yyparse();
@@ -59,7 +57,7 @@ parser(char *str, Oid *typev, int nargs)
 	clearerr(stdin);
 
 	if (yyresult)				/* error */
-		return (QueryTreeList *) NULL;
+		return (List *) NULL;
 
 	queryList = parse_analyze(parsetree, NULL);
 
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index c5503a6f0b18c765f69b1a016032e7dd38eda471..a5300e5672a5e835bbd03c81efd26be661d9f7fc 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.40 1999/05/12 17:04:47 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.41 1999/05/13 07:28:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3107,25 +3107,25 @@ void create_list(Node *ptr, List **intersect_list)
  * instead. */
 Node *intersect_tree_analyze(Node *tree, Node *first_select, Node *parsetree)
 {
-  Node *result = (Node *)NIL;
-  List *arg;
-  
-  if(IsA(tree, SelectStmt))
+	Node *result = (Node *) NIL;
+	List *arg;
+
+	if (IsA(tree, SelectStmt))
     {
-      QueryTreeList *qtree;
-      
-      /* If we get to the tree given in first_select return
-       * parsetree instead of performing parse_analyze() */
-      if(tree == first_select){
-	result = parsetree;
-      }
-      else {	
-	/* transform the 'raw' nodes to 'cooked' Query nodes */ 
-	qtree = parse_analyze(lcons(tree, NIL), NULL);
-	result = (Node *)qtree->qtrees[0];	
-      }
-      
+		/* If we get to the tree given in first_select return
+		 * parsetree instead of performing parse_analyze() */
+		if (tree == first_select)
+		{
+			result = parsetree;
+		}
+		else
+		{	
+			/* transform the 'raw' nodes to 'cooked' Query nodes */ 
+			List *qtree = parse_analyze(lcons(tree, NIL), NULL);
+			result = (Node *) lfirst(qtree);
+		}
     }  
+
   if(IsA(tree,Expr))
     {
       /* Call recursively for every argument of the node */
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 0a1a45b4dbf7348875c6fd9de387cd97bea0e259..53f8f9186978d95e291058e228003ed808a99d98 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.112 1999/05/11 09:06:31 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.113 1999/05/13 07:28:46 tgl Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -389,19 +389,17 @@ List *
 pg_parse_and_plan(char *query_string,	/* string to execute */
 				  Oid *typev,	/* argument types */
 				  int nargs,	/* number of arguments */
-				  QueryTreeList **queryListP,	/* pointer to the parse
-												 * trees */
+				  List **queryListP,	/* returned pointer to the parse trees */
 				  CommandDest dest,		/* where results should go */
 				  bool aclOverride)
 {
-	QueryTreeList *querytree_list;
-	int			i;
+	List	   *querytree_list = NIL;
 	List	   *plan_list = NIL;
-	Plan	   *plan;
-	int			j;
-	QueryTreeList *new_list;
-	List	   *rewritten = NIL;
+	List	   *querytree_list_item;
 	Query	   *querytree;
+	Plan	   *plan;
+	List	   *new_list;
+	List	   *rewritten;
 
 	if (DebugPrintQuery)
 	{
@@ -461,22 +459,17 @@ pg_parse_and_plan(char *query_string,	/* string to execute */
 		ShowUsage();
 	}
 
-	/* new_list holds the rewritten queries */
-	new_list = (QueryTreeList *) malloc(sizeof(QueryTreeList));
-	new_list->len = querytree_list->len;
-	new_list->qtrees = (Query **) malloc(new_list->len * sizeof(Query *));
-
 	/* ----------------
 	 *	(2) rewrite the queries, as necessary
 	 *
-	 *  j counts queries output into new_list; the number of rewritten
-	 *  queries can be different from the original number.
+	 *  rewritten queries are collected in new_list.  Note there may be
+	 *  more or fewer than in the original list.
 	 * ----------------
 	 */
-	j = 0;
-	for (i = 0; i < querytree_list->len; i++)
+	new_list = NIL;
+	foreach (querytree_list_item, querytree_list)
 	{
-		querytree = querytree_list->qtrees[i];
+		querytree = (Query *) lfirst(querytree_list_item);
 
 		if (DebugPrintParse || DebugPPrintParse)
 		{
@@ -489,46 +482,19 @@ pg_parse_and_plan(char *query_string,	/* string to execute */
 			}
 		}
 
-		/* don't rewrite utilites, just dump 'em into new_list */
 		if (querytree->commandType == CMD_UTILITY)
 		{
-			new_list->qtrees[j++] = querytree;
-			continue;
+			/* don't rewrite utilities, just dump 'em into new_list */
+			new_list = lappend(new_list, querytree);
 		}
-
-		/* rewrite regular queries */
-		rewritten = QueryRewrite(querytree);
-
-		if (rewritten != NIL)
+		else
 		{
-			int			len,
-						k;
-
-			len = length(rewritten);
-			if (len == 1)
-				new_list->qtrees[j++] = (Query *) lfirst(rewritten);
-			else
-			{
-				/* rewritten queries are longer than original query */
-				/* grow the new_list to accommodate */
-				new_list->len += len - 1;		/* - 1 because originally
-												 * we allocated one space
-												 * for the query */
-				new_list->qtrees = realloc(new_list->qtrees,
-										   new_list->len * sizeof(Query *));
-				for (k = 0; k < len; k++)
-					new_list->qtrees[j++] = (Query *) nth(k, rewritten);
-			}
+			/* rewrite regular queries */
+			rewritten = QueryRewrite(querytree);
+			new_list = nconc(new_list, rewritten);
 		}
 	}
 
-	/* Update new_list with correct final length */
-	new_list->len = j;
-
-	/* we're done with the original lists, free it */
-	free(querytree_list->qtrees);
-	free(querytree_list);
-
 	querytree_list = new_list;
 
 	/*
@@ -536,18 +502,18 @@ pg_parse_and_plan(char *query_string,	/* string to execute */
 	 */
 	if (aclOverride)
 	{
-		for (i = 0; i < querytree_list->len; i++)
+		foreach (querytree_list_item, querytree_list)
 		{
-			RangeTblEntry *rte;
 			List	   *l;
 
-			querytree = querytree_list->qtrees[i];
+			querytree = (Query *) lfirst(querytree_list_item);
+
 			if (querytree->commandType == CMD_UTILITY)
 				continue;
 
 			foreach(l, querytree->rtable)
 			{
-				rte = (RangeTblEntry *) lfirst(l);
+				RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
 
 				rte->skipAcl = TRUE;
 			}
@@ -559,24 +525,26 @@ pg_parse_and_plan(char *query_string,	/* string to execute */
 		if (DebugPPrintRewrittenParsetree) {
 			TPRINTF(TRACE_PRETTY_REWRITTEN, "after rewriting:");
 
-			for (i = 0; i < querytree_list->len; i++)
+			foreach (querytree_list_item, querytree_list)
 			{
-				nodeDisplay(querytree_list->qtrees[i]);
+				querytree = (Query *) lfirst(querytree_list_item);
+				nodeDisplay(querytree);
 				printf("\n");
 			}
 		} else {
 			TPRINTF(TRACE_REWRITTEN, "after rewriting:");
 
-			for (i = 0; i < querytree_list->len; i++)
+			foreach (querytree_list_item, querytree_list)
 			{
-				printf("\n%s\n\n", nodeToString(querytree_list->qtrees[i]));
+				querytree = (Query *) lfirst(querytree_list_item);
+				printf("\n%s\n\n", nodeToString(querytree));
 			}
 		}
 	}
 
-	for (i = 0; i < querytree_list->len; i++)
+	foreach (querytree_list_item, querytree_list)
 	{
-		querytree = querytree_list->qtrees[i];
+		querytree = (Query *) lfirst(querytree_list_item);
 
 		/*
 		 * For each query that isn't a utility invocation, generate a
@@ -600,11 +568,9 @@ pg_parse_and_plan(char *query_string,	/* string to execute */
 				elog(NOTICE, "(transaction aborted): %s",
 					 "queries ignored until END");
 
-				free(querytree_list->qtrees);
-				free(querytree_list);
 				if (queryListP)
-					*queryListP = (QueryTreeList *) NULL;
-				return (List *) NULL;
+					*queryListP = NIL;
+				return NIL;
 			}
 
 			if (ShowPlannerStats)
@@ -638,8 +604,6 @@ pg_parse_and_plan(char *query_string,	/* string to execute */
 			}
 #endif
 		}
-#ifdef FUNC_UTIL_PATCH
-
 		/*
 		 * If the command is an utility append a null plan. This is needed
 		 * to keep the plan_list aligned with the querytree_list or the
@@ -647,18 +611,6 @@ pg_parse_and_plan(char *query_string,	/* string to execute */
 		 */
 		else
 			plan_list = lappend(plan_list, NULL);
-#endif
-	}
-
-	/* ----------
-	 * Check if the rewriting had thrown away everything
-	 * ----------
-	 */
-	if (querytree_list->len == 0)
-	{
-		free(querytree_list->qtrees);
-		free(querytree_list);
-		querytree_list = NULL;
 	}
 
 	if (queryListP)
@@ -702,36 +654,39 @@ pg_exec_query_dest(char *query_string,	/* string to execute */
 				   bool aclOverride)	/* to give utility commands power
 										 * of superusers */
 {
+	List	   *querytree_list;
 	List	   *plan_list;
-	Plan	   *plan;
 	Query	   *querytree;
-	int			i,
-				j;
-	QueryTreeList *querytree_list;
+	Plan	   *plan;
+	int			j;
 
 	/* plan the queries */
-	plan_list = pg_parse_and_plan(query_string, NULL, 0, &querytree_list, dest, aclOverride);
+	plan_list = pg_parse_and_plan(query_string, NULL, 0,
+								  &querytree_list, dest, aclOverride);
 
+	/* if we got a cancel signal whilst planning, quit */
 	if (QueryCancel)
 		CancelQuery();
 
-	/* pg_parse_and_plan could have failed */
-	if (querytree_list == NULL)
-		return;
-
-	for (i = 0; i < querytree_list->len; i++)
-	{
-		querytree = querytree_list->qtrees[i];
+	/* OK, do it to it! */
 
-#ifdef FUNC_UTIL_PATCH
+	/* NOTE: we do not use "foreach" here because we want to be sure
+	 * the list pointers have been advanced before the query is executed.
+	 * We need to do that because VACUUM has a nasty little habit of doing
+	 * CommitTransactionCommand at startup, and that will release the
+	 * memory holding our parse/plan lists :-(.  This needs a better
+	 * solution --- currently, the code will crash if someone submits
+	 * "vacuum; something-else" in a single query string.  But memory
+	 * allocation needs redesigned anyway, so this will have to do for now.
+	 */
 
-		/*
-		 * Advance on the plan_list in every case.	Now the plan_list has
-		 * the same length of the querytree_list.  DZ - 30-8-1996
-		 */
+	while (querytree_list)
+	{
+		querytree = (Query *) lfirst(querytree_list);
+		querytree_list = lnext(querytree_list);
 		plan = (Plan *) lfirst(plan_list);
 		plan_list = lnext(plan_list);
-#endif
+
 		if (querytree->commandType == CMD_UTILITY)
 		{
 			/* ----------------
@@ -747,19 +702,9 @@ pg_exec_query_dest(char *query_string,	/* string to execute */
 				TPRINTF(TRACE_VERBOSE, "ProcessUtility");
 
 			ProcessUtility(querytree->utilityStmt, dest);
-
 		}
 		else
 		{
-#ifndef FUNC_UTIL_PATCH
-
-			/*
-			 * Moved before the if.  DZ - 30-8-1996
-			 */
-			plan = (Plan *) lfirst(plan_list);
-			plan_list = lnext(plan_list);
-#endif
-
 #ifdef INDEXSCAN_PATCH
 
 			/*
@@ -810,12 +755,8 @@ pg_exec_query_dest(char *query_string,	/* string to execute */
 		 * visible to subsequent ones.
 		 */
 
-		if (querytree_list)
-			CommandCounterIncrement();
+		CommandCounterIncrement();
 	}
-
-	free(querytree_list->qtrees);
-	free(querytree_list);
 }
 
 /* --------------------------------
@@ -1544,7 +1485,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
 	if (!IsUnderPostmaster)
 	{
 		puts("\nPOSTGRES backend interactive interface ");
-		puts("$Revision: 1.112 $ $Date: 1999/05/11 09:06:31 $\n");
+		puts("$Revision: 1.113 $ $Date: 1999/05/13 07:28:46 $\n");
 	}
 
 	/* ----------------
diff --git a/src/include/executor/spi_priv.h b/src/include/executor/spi_priv.h
index 0ed47bf1e1d19fcaf109d67abd3591cc93b4f706..ece8a5a1c74abf256604dc5a88df52c114d05b73 100644
--- a/src/include/executor/spi_priv.h
+++ b/src/include/executor/spi_priv.h
@@ -3,7 +3,7 @@
  * spi.c
  *				Server Programming Interface private declarations
  *
- * $Header: /cvsroot/pgsql/src/include/executor/spi_priv.h,v 1.2 1999/02/13 23:21:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/include/executor/spi_priv.h,v 1.3 1999/05/13 07:28:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -15,7 +15,7 @@
 
 typedef struct
 {
-	QueryTreeList *qtlist;		/* malloced */
+	List	   *qtlist;
 	uint32		processed;		/* by Executor */
 	SPITupleTable *tuptable;
 	Portal		portal;			/* portal per procedure */
@@ -25,7 +25,7 @@ typedef struct
 
 typedef struct
 {
-	QueryTreeList *qtlist;
+	List	   *qtlist;
 	List	   *ptlist;
 	int			nargs;
 	Oid		   *argtypes;
diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h
index 12411789683fea3a4b5fd98593d0def362d632c8..6bad60b6ada2c8fe9f7ed5c7c10041f13828811f 100644
--- a/src/include/optimizer/planner.h
+++ b/src/include/optimizer/planner.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: planner.h,v 1.10 1999/02/13 23:21:51 momjian Exp $
+ * $Id: planner.h,v 1.11 1999/05/13 07:29:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,6 +22,6 @@
 
 extern Plan *planner(Query *parse);
 extern Plan *union_planner(Query *parse);
-extern void pg_checkretval(Oid rettype, QueryTreeList *querytree_list);
+extern void pg_checkretval(Oid rettype, List *querytree_list);
 
 #endif	 /* PLANNER_H */
diff --git a/src/include/parser/analyze.h b/src/include/parser/analyze.h
index 4be7637d744003a04489d19a09e7b47960972b1f..af775c84f896749defa6a55bf84c8c76f1b1a6f0 100644
--- a/src/include/parser/analyze.h
+++ b/src/include/parser/analyze.h
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: analyze.h,v 1.5 1999/01/18 00:10:11 momjian Exp $
+ * $Id: analyze.h,v 1.6 1999/05/13 07:29:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -14,7 +14,7 @@
 
 #include <parser/parse_node.h>
 
-extern QueryTreeList *parse_analyze(List *pl, ParseState *parentParseState);
+extern List *parse_analyze(List *pl, ParseState *parentParseState);
 /***S*I***/
 extern void create_select_list(Node *ptr, List **select_list, bool *unionall_present);
 extern Node *A_Expr_to_Expr(Node *ptr, bool *intersect_present);
diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h
index 23040b572398751743ac9bf6c0c8715d5fc393e7..9bc4cf2b13bbde2af6b8f2e477a22ccfa260a7d3 100644
--- a/src/include/parser/parse_node.h
+++ b/src/include/parser/parse_node.h
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_node.h,v 1.11 1998/09/01 04:37:35 momjian Exp $
+ * $Id: parse_node.h,v 1.12 1999/05/13 07:29:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,12 +19,6 @@
 #include <parser/parse_type.h>
 #include <utils/rel.h>
 
-typedef struct QueryTreeList
-{
-	int			len;			/* number of queries */
-	Query	  **qtrees;
-} QueryTreeList;
-
 /* state information used during parse analysis */
 typedef struct ParseState
 {
diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h
index 8d13e0288092f01a635f9403745a3c24656c8f92..50b99b48ce6b169253c89048955e71e4944a3fb5 100644
--- a/src/include/parser/parser.h
+++ b/src/include/parser/parser.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parser.h,v 1.4 1998/09/01 04:37:42 momjian Exp $
+ * $Id: parser.h,v 1.5 1999/05/13 07:29:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -15,6 +15,6 @@
 
 #include <parser/parse_node.h>
 
-extern QueryTreeList *parser(char *str, Oid *typev, int nargs);
+extern List *parser(char *str, Oid *typev, int nargs);
 
 #endif	 /* PARSER_H */
diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h
index 96da4d56653125da2a494a286465aa2e40fdae0b..41bcaa43f394107fdea092f7bdbb99d396cb4946 100644
--- a/src/include/tcop/tcopprot.h
+++ b/src/include/tcop/tcopprot.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: tcopprot.h,v 1.18 1999/04/20 02:19:55 tgl Exp $
+ * $Id: tcopprot.h,v 1.19 1999/05/13 07:29:22 tgl Exp $
  *
  * OLD COMMENTS
  *	  This file was created so that other c files could get the two
@@ -41,8 +41,8 @@ extern bool InError;
 
 #ifndef BOOTSTRAP_INCLUDE
 extern List *pg_parse_and_plan(char *query_string, Oid *typev, int nargs,
-				  QueryTreeList **queryListP, CommandDest dest,
-				  bool aclOverride);
+							   List **queryListP, CommandDest dest,
+							   bool aclOverride);
 extern void pg_exec_query(char *query_string);
 extern void pg_exec_query_acl_override(char *query_string);
 extern void