diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 08ed6a7316341f4e19d4684f052b4bfa118186d4..1971ccb9282faedacfac42c33768e2a7a89ffeb9 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.35 1999/07/24 23:21:12 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.36 1999/08/10 03:00:14 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -51,28 +51,29 @@ static Oid	hashjoinop(Expr *clause);
 void
 make_var_only_tlist(Query *root, List *tlist)
 {
-	List	   *tlist_vars = NIL;
-	List	   *l = NIL;
-	List	   *tvar = NIL;
+	List	   *tlist_vars = pull_var_clause((Node *) tlist);
 
-	foreach(l, tlist)
-	{
-		TargetEntry *entry = (TargetEntry *) lfirst(l);
+	add_vars_to_targetlist(root, tlist_vars);
+	freeList(tlist_vars);
+}
 
-		tlist_vars = nconc(tlist_vars, pull_var_clause(entry->expr));
-	}
+/*
+ * add_vars_to_targetlist
+ *	  For each variable appearing in the list, add it to the relation's
+ *	  targetlist if not already present.  Rel nodes will also be created
+ *	  if not already present.
+ */
+static void
+add_vars_to_targetlist(Query *root, List *vars)
+{
+	List	   *temp;
 
-	/* now, the target list only contains Var nodes */
-	foreach(tvar, tlist_vars)
+	foreach(temp, vars)
 	{
-		Var		   *var = (Var *) lfirst(tvar);
-		Index		varno;
-		RelOptInfo *result;
-
-		varno = var->varno;
-		result = get_base_rel(root, varno);
+		Var		   *var = (Var *) lfirst(temp);
+		RelOptInfo *rel = get_base_rel(root, var->varno);
 
-		add_var_to_tlist(result, var);
+		add_var_to_tlist(rel, var);
 	}
 }
 
@@ -87,31 +88,30 @@ make_var_only_tlist(Query *root, List *tlist)
 void
 add_missing_vars_to_tlist(Query *root, List *tlist)
 {
+	int			varno = 1;
 	List	   *l;
-	int			varno;
 
-	varno = 1;
 	foreach(l, root->rtable)
 	{
 		RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
 		Relids		relids;
-		RelOptInfo *result;
-		Var		   *var;
 
 		relids = lconsi(varno, NIL);
 		if (rte->inFromCl && !rel_member(relids, root->base_rel_list))
 		{
+			RelOptInfo *rel;
+			Var		   *var;
+
+			/* add it to base_rel_list */
+			rel = get_base_rel(root, varno);
+			/* give it a dummy tlist entry for its OID */
 			var = makeVar(varno, ObjectIdAttributeNumber,
 						  OIDOID, -1, 0, varno, ObjectIdAttributeNumber);
-			/* add it to base_rel_list */
-			result = get_base_rel(root, varno);
-			add_var_to_tlist(result, var);
+			add_var_to_tlist(rel, var);
 		}
 		pfree(relids);
 		varno++;
 	}
-
-	return;
 }
 
 /*****************************************************************************
@@ -239,26 +239,6 @@ add_join_info_to_rels(Query *root, RestrictInfo *restrictinfo,
 	}
 }
 
-/*
- * add_vars_to_targetlist
- *	  For each variable appearing in a clause, add it to the relation's
- *	  targetlist if not already present.
- */
-static void
-add_vars_to_targetlist(Query *root, List *vars)
-{
-	List	   *temp;
-
-	foreach(temp, vars)
-	{
-		Var		   *var = (Var *) lfirst(temp);
-		RelOptInfo *rel = get_base_rel(root, var->varno);
-
-		if (tlistentry_member(var, rel->targetlist) == NULL)
-			add_var_to_tlist(rel, var);
-	}
-}
-
 /*****************************************************************************
  *
  *	 JOININFO
@@ -269,7 +249,7 @@ add_vars_to_targetlist(Query *root, List *vars)
  * set_joininfo_mergeable_hashable
  *	  Set the MergeJoinable or HashJoinable field for every joininfo node
  *	  (within a rel node) and the mergejoinorder or hashjoinop field for
- *	  each restrictinfo node(within a joininfo node) for all relations in a
+ *	  each restrictinfo node (within a joininfo node) for all relations in a
  *	  query.
  *
  *	  Returns nothing.
@@ -277,43 +257,43 @@ add_vars_to_targetlist(Query *root, List *vars)
 void
 set_joininfo_mergeable_hashable(List *rel_list)
 {
-	List	   *x,
-			   *y,
-			   *z;
-	RelOptInfo *rel;
-	JoinInfo   *joininfo;
-	RestrictInfo *restrictinfo;
-	Expr	   *clause;
+	List	   *x;
 
 	foreach(x, rel_list)
 	{
-		rel = (RelOptInfo *) lfirst(x);
+		RelOptInfo *rel = (RelOptInfo *) lfirst(x);
+		List	   *y;
+
 		foreach(y, rel->joininfo)
 		{
-			joininfo = (JoinInfo *) lfirst(y);
+			JoinInfo   *joininfo = (JoinInfo *) lfirst(y);
+			List	   *z;
+
 			foreach(z, joininfo->jinfo_restrictinfo)
 			{
-				restrictinfo = (RestrictInfo *) lfirst(z);
-				clause = restrictinfo->clause;
+				RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(z);
+				Expr	   *clause = restrictinfo->clause;
+
 				if (is_joinable((Node *) clause))
 				{
-					MergeOrder *sortop = (MergeOrder *) NULL;
-					Oid			hashop = (Oid) NULL;
-
 					if (_enable_mergejoin_)
-						sortop = mergejoinop(clause);
-					if (sortop)
 					{
-						restrictinfo->mergejoinorder = sortop;
-						joininfo->mergejoinable = true;
+						MergeOrder *sortop = mergejoinop(clause);
+						if (sortop)
+						{
+							restrictinfo->mergejoinorder = sortop;
+							joininfo->mergejoinable = true;
+						}
 					}
 
 					if (_enable_hashjoin_)
-						hashop = hashjoinop(clause);
-					if (hashop)
 					{
-						restrictinfo->hashjoinoperator = hashop;
-						joininfo->hashjoinable = true;
+						Oid			hashop = hashjoinop(clause);
+						if (hashop)
+						{
+							restrictinfo->hashjoinoperator = hashop;
+							joininfo->hashjoinable = true;
+						}
 					}
 				}
 			}
@@ -323,8 +303,8 @@ set_joininfo_mergeable_hashable(List *rel_list)
 
 /*
  * mergejoinop
- *	  Returns the mergejoin operator of an operator iff 'clause' is
- *	  mergejoinable, i.e., both operands are single vars and the operator is
+ *	  Returns a MergeOrder node for 'clause' iff 'clause' is mergejoinable,
+ *	  i.e., both operands are single vars and the operator is
  *	  a mergejoinable operator.
  */
 static MergeOrder *
@@ -346,7 +326,7 @@ mergejoinop(Expr *clause)
 	/* caution: is_opclause accepts more than I do, so check it */
 	if (!right)
 		return NULL;			/* unary opclauses need not apply */
-	if (!IsA(left, Var) ||!IsA(right, Var))
+	if (!IsA(left, Var) || !IsA(right, Var))
 		return NULL;
 
 	opno = ((Oper *) clause->oper)->opno;
@@ -374,8 +354,8 @@ mergejoinop(Expr *clause)
 
 /*
  * hashjoinop
- *	  Returns the hashjoin operator of an operator iff 'clause' is
- *	  hashjoinable, i.e., both operands are single vars and the operator is
+ *	  Returns the hashjoin operator iff 'clause' is hashjoinable,
+ *	  i.e., both operands are single vars and the operator is
  *	  a hashjoinable operator.
  */
 static Oid
@@ -393,7 +373,7 @@ hashjoinop(Expr *clause)
 	/* caution: is_opclause accepts more than I do, so check it */
 	if (!right)
 		return InvalidOid;		/* unary opclauses need not apply */
-	if (!IsA(left, Var) ||!IsA(right, Var))
+	if (!IsA(left, Var) || !IsA(right, Var))
 		return InvalidOid;
 
 	return op_hashjoinable(((Oper *) clause->oper)->opno,
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 7bc70bd22c4bee76320e6871ed5d05a8cae553d8..322aeba1ce3db5bce5d257d92329dfb21973401e 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.44 1999/08/09 00:51:24 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.45 1999/08/10 03:00:15 tgl Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -78,7 +78,8 @@ bool
 is_opclause(Node *clause)
 {
 	return (clause != NULL &&
-	  nodeTag(clause) == T_Expr && ((Expr *) clause)->opType == OP_EXPR);
+			IsA(clause, Expr) &&
+			((Expr *) clause)->opType == OP_EXPR);
 }
 
 /*
@@ -147,7 +148,7 @@ bool
 is_funcclause(Node *clause)
 {
 	return (clause != NULL &&
-			nodeTag(clause) == T_Expr &&
+			IsA(clause, Expr) &&
 			((Expr *) clause)->opType == FUNC_EXPR);
 }
 
@@ -183,9 +184,9 @@ make_funcclause(Func *func, List *funcargs)
 bool
 or_clause(Node *clause)
 {
-	return clause != NULL &&
-	nodeTag(clause) == T_Expr &&
-	((Expr *) clause)->opType == OR_EXPR;
+	return (clause != NULL &&
+			IsA(clause, Expr) &&
+			((Expr *) clause)->opType == OR_EXPR);
 }
 
 /*
@@ -220,7 +221,7 @@ bool
 not_clause(Node *clause)
 {
 	return (clause != NULL &&
-			nodeTag(clause) == T_Expr &&
+			IsA(clause, Expr) &&
 			((Expr *) clause)->opType == NOT_EXPR);
 }
 
@@ -269,7 +270,7 @@ bool
 and_clause(Node *clause)
 {
 	return (clause != NULL &&
-			nodeTag(clause) == T_Expr &&
+			IsA(clause, Expr) &&
 			((Expr *) clause)->opType == AND_EXPR);
 }
 
@@ -319,27 +320,10 @@ make_ands_implicit(Expr *clause)
 		return lcons(clause, NIL);
 }
 
-/*****************************************************************************
- *		CASE clause functions
- *****************************************************************************/
-
-
-/*
- * case_clause
- *
- * Returns t iff its argument is a 'case' clause: (CASE { expr }).
- *
- */
-bool
-case_clause(Node *clause)
-{
-	return (clause != NULL &&
-			nodeTag(clause) == T_CaseExpr);
-}
 
 /*****************************************************************************
  *																			 *
- *																			 *
+ *		General clause-manipulating routines								 *
  *																			 *
  *****************************************************************************/
 
@@ -374,20 +358,21 @@ pull_constant_clauses(List *quals, List **constantQual)
 
 /*
  * clause_relids_vars
- *	  Retrieves relids and vars appearing within a clause.
- *	  Returns ((relid1 relid2 ... relidn) (var1 var2 ... varm)) where
- *	  vars appear in the clause  this is done by recursively searching
- *	  through the left and right operands of a clause.
- *
- * Returns the list of relids and vars.
+ *	  Retrieves distinct relids and vars appearing within a clause.
  *
+ * '*relids' is set to an integer list of all distinct "varno"s appearing
+ *		in Vars within the clause.
+ * '*vars' is set to a list of all distinct Vars appearing within the clause.
+ *		Var nodes are considered distinct if they have different varno
+ *		or varattno values.  If there are several occurrences of the same
+ *		varno/varattno, you get a randomly chosen one...
  */
 void
 clause_get_relids_vars(Node *clause, Relids *relids, List **vars)
 {
 	List	   *clvars = pull_var_clause(clause);
-	List	   *var_list = NIL;
 	List	   *varno_list = NIL;
+	List	   *var_list = NIL;
 	List	   *i;
 
 	foreach(i, clvars)
@@ -397,7 +382,7 @@ clause_get_relids_vars(Node *clause, Relids *relids, List **vars)
 
 		Assert(var->varlevelsup == 0);
 		if (!intMember(var->varno, varno_list))
-			varno_list = lappendi(varno_list, var->varno);
+			varno_list = lconsi(var->varno, varno_list);
 		foreach(vi, var_list)
 		{
 			Var		   *in_list = (Var *) lfirst(vi);
@@ -407,7 +392,7 @@ clause_get_relids_vars(Node *clause, Relids *relids, List **vars)
 				break;
 		}
 		if (vi == NIL)
-			var_list = lappend(var_list, var);
+			var_list = lcons(var, var_list);
 	}
 	freeList(clvars);
 
@@ -424,22 +409,10 @@ clause_get_relids_vars(Node *clause, Relids *relids, List **vars)
 int
 NumRelids(Node *clause)
 {
-	List	   *vars = pull_var_clause(clause);
-	List	   *var_list = NIL;
-	List	   *i;
-	int			result;
+	List	   *varno_list = pull_varnos(clause);
+	int			result = length(varno_list);
 
-	foreach(i, vars)
-	{
-		Var		   *var = (Var *) lfirst(i);
-
-		if (!intMember(var->varno, var_list))
-			var_list = lconsi(var->varno, var_list);
-	}
-
-	result = length(var_list);
-	freeList(vars);
-	freeList(var_list);
+	freeList(varno_list);
 	return result;
 }
 
@@ -468,7 +441,7 @@ is_joinable(Node *clause)
 	 * One side of the clause (i.e. left or right operands) must either be
 	 * a var node ...
 	 */
-	if (IsA(leftop, Var) ||IsA(rightop, Var))
+	if (IsA(leftop, Var) || IsA(rightop, Var))
 		return true;
 
 	/*
@@ -480,36 +453,6 @@ is_joinable(Node *clause)
 	return false;
 }
 
-/*
- * qual_clause_p
- *
- * Returns t iff 'clause' is a valid qualification clause.
- *
- * For now we accept only "var op const" or "const op var".
- */
-bool
-qual_clause_p(Node *clause)
-{
-	Node	   *leftop,
-			   *rightop;
-
-	if (!is_opclause(clause))
-		return false;
-
-	leftop = (Node *) get_leftop((Expr *) clause);
-	rightop = (Node *) get_rightop((Expr *) clause);
-
-	if (!rightop)
-		return false;			/* unary opclauses need not apply */
-
-	/* How about Param-s ?	- vadim 02/03/98 */
-	if (IsA(leftop, Var) &&IsA(rightop, Const))
-		return true;
-	if (IsA(rightop, Var) &&IsA(leftop, Const))
-		return true;
-	return false;
-}
-
 /*
  * fix_opids
  *	  Calculate opid field from opno for each Oper node in given tree.
@@ -644,24 +587,16 @@ static int is_single_func(Node *node)
 {
 	if (is_funcclause(node))
 	{
-		List	   *vars = pull_var_clause(node);
+		List	   *varnos = pull_varnos(node);
 
-		if (vars != NIL)
+		if (length(varnos) == 1)
 		{
-			int		funcvarno = ((Var *) lfirst(vars))->varno;
-			List   *v;
-			/* need to check that all args of func are same relation */
-			foreach(v, lnext(vars))
-			{
-				if (((Var *) lfirst(v))->varno != funcvarno)
-				{
-					funcvarno = 0;
-					break;
-				}
-			}
-			freeList(vars);
+			int		funcvarno = lfirsti(varnos);
+
+			freeList(varnos);
 			return funcvarno;
 		}
+		freeList(varnos);
 	}
 	return 0;
 }
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index 386f23dba85c9fd778e534d672c3286334f245c2..921bb1d671a2627fa9760550b373dd166ca1eb2f 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.37 1999/08/09 05:34:13 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.38 1999/08/10 03:00:15 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -285,37 +285,31 @@ copy_vars(List *target, List *source)
 List *
 flatten_tlist(List *tlist)
 {
+	List	   *vlist = pull_var_clause((Node *) tlist);
 	int			last_resdomno = 1;
 	List	   *new_tlist = NIL;
-	List	   *tl;
+	List	   *v;
 
-	foreach(tl, tlist)
+	foreach(v, vlist)
 	{
-		TargetEntry *tl_entry = (TargetEntry *) lfirst(tl);
-		List	   *vlist = pull_var_clause((Node *) get_expr(tl_entry));
-		List	   *v;
+		Var		   *var = lfirst(v);
 
-		foreach(v, vlist)
+		if (! tlistentry_member(var, new_tlist))
 		{
-			Var		   *var = lfirst(v);
-
-			if (! tlistentry_member(var, new_tlist))
-			{
-				Resdom	   *r;
-
-				r = makeResdom(last_resdomno++,
-							   var->vartype,
-							   var->vartypmod,
-							   NULL,
-							   (Index) 0,
-							   (Oid) 0,
-							   false);
-				new_tlist = lappend(new_tlist,
-									makeTargetEntry(r, (Node *) var));
-			}
+			Resdom	   *r;
+
+			r = makeResdom(last_resdomno++,
+						   var->vartype,
+						   var->vartypmod,
+						   NULL,
+						   (Index) 0,
+						   (Oid) 0,
+						   false);
+			new_tlist = lappend(new_tlist,
+								makeTargetEntry(r, (Node *) var));
 		}
-		freeList(vlist);
 	}
+	freeList(vlist);
 
 	return new_tlist;
 }
@@ -334,20 +328,8 @@ flatten_tlist(List *tlist)
 List *
 flatten_tlist_vars(List *full_tlist, List *flat_tlist)
 {
-	List	   *result = NIL;
-	List	   *x;
-
-	foreach(x, full_tlist)
-	{
-		TargetEntry *tle = lfirst(x);
-
-		result = lappend(result,
-						 makeTargetEntry(tle->resdom,
-							flatten_tlist_vars_mutator((Node *) get_expr(tle),
-													   flat_tlist)));
-	}
-
-	return result;
+	return (List *) flatten_tlist_vars_mutator((Node *) full_tlist,
+											   flat_tlist);
 }
 
 static Node *
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index 5e3ea9e492d9428e7450405896e99cc81955b20e..be181ea626f2bce9d8826359700eb6a6bd6ee006 100644
--- a/src/backend/optimizer/util/var.c
+++ b/src/backend/optimizer/util/var.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.21 1999/07/15 22:39:32 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.22 1999/08/10 03:00:15 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -15,12 +15,10 @@
 
 #include "postgres.h"
 
-
 #include "optimizer/clauses.h"
 #include "optimizer/var.h"
 
 
-
 static bool pull_varnos_walker(Node *node, List **listptr);
 static bool contain_var_clause_walker(Node *node, void *context);
 static bool pull_var_clause_walker(Node *node, List **listptr);
@@ -111,22 +109,23 @@ pull_var_clause_walker(Node *node, List **listptr)
 /*
  *		var_equal
  *
- *		The only difference between this an equal() is that this does not
- *		test varnoold and varoattno.
+ *		This is like equal() except that it does NOT test varnoold and
+ *		varoattno.  Also, it will not compare non-Var nodes.
  *
  *		Returns t iff two var nodes correspond to the same attribute.
  */
 bool
 var_equal(Var *var1, Var *var2)
 {
-	if (IsA(var1, Var) &&IsA(var2, Var) &&
-		(((Var *) var1)->varno == ((Var *) var2)->varno) &&
-		(((Var *) var1)->vartype == ((Var *) var2)->vartype) &&
-		(((Var *) var1)->vartypmod == ((Var *) var2)->vartypmod) &&
-		(((Var *) var1)->varlevelsup == ((Var *) var2)->varlevelsup) &&
-		(((Var *) var1)->varattno == ((Var *) var2)->varattno))
+	if (var1 != NULL && IsA(var1, Var) &&
+		var2 != NULL && IsA(var2, Var) &&
+		var1->varno == var2->varno &&
+		var1->varattno == var2->varattno &&
+		var1->vartype == var2->vartype &&
+		var1->vartypmod == var2->vartypmod &&
+		var1->varlevelsup == var2->varlevelsup)
 	{
-		Assert(((Var *) var1)->varlevelsup == 0);
+		Assert(var1->varlevelsup == 0);	/* XXX why do this here??? */
 		return true;
 	}
 	else
diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h
index 9fa4ff245ce72eb280fb8c81652a963121e15c9b..3ebf442791222c9f6a83d7f6a34fc8e1c2ee3d80 100644
--- a/src/include/optimizer/clauses.h
+++ b/src/include/optimizer/clauses.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: clauses.h,v 1.25 1999/08/09 00:51:23 tgl Exp $
+ * $Id: clauses.h,v 1.26 1999/08/10 03:00:12 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -37,13 +37,10 @@ extern Expr *make_andclause(List *andclauses);
 extern Expr *make_ands_explicit(List *andclauses);
 extern List *make_ands_implicit(Expr *clause);
 
-extern bool case_clause(Node *clause);
-
 extern List *pull_constant_clauses(List *quals, List **constantQual);
 extern void clause_get_relids_vars(Node *clause, Relids *relids, List **vars);
 extern int	NumRelids(Node *clause);
 extern bool is_joinable(Node *clause);
-extern bool qual_clause_p(Node *clause);
 extern List *fix_opids(List *clauses);
 extern void get_relattval(Node *clause, int targetrelid,
 						  int *relid, AttrNumber *attno,