diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index b925517d7b1590951da71a5bc307bf678c61c0ea..6b13dab764529cae788b1a2426b3be634a20e5a4 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.79 2003/08/04 02:39:59 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeHash.c,v 1.80 2003/11/25 21:00:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -113,6 +113,7 @@ ExecInitHash(Hash *node, EState *estate)
 	hashstate->ps.plan = (Plan *) node;
 	hashstate->ps.state = estate;
 	hashstate->hashtable = NULL;
+	hashstate->hashkeys = NIL;	/* will be set by parent HashJoin */
 
 	/*
 	 * Miscellaneous initialization
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 112155bdd376c77f79f07f6d63236876c45eb3ce..be0543ac61373b0d61405ecd5db8507f6c9bd1aa 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.57 2003/09/25 06:57:59 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeHashjoin.c,v 1.58 2003/11/25 21:00:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -308,7 +308,8 @@ ExecInitHashJoin(HashJoin *node, EState *estate)
 	HashJoinState *hjstate;
 	Plan	   *outerNode;
 	Hash	   *hashNode;
-	List	   *hclauses;
+	List	   *lclauses;
+	List	   *rclauses;
 	List	   *hoperators;
 	List	   *hcl;
 
@@ -410,31 +411,31 @@ ExecInitHashJoin(HashJoin *node, EState *estate)
 	hjstate->hj_CurTuple = (HashJoinTuple) NULL;
 
 	/*
-	 * The planner already made a list of the inner hashkeys for us, but
-	 * we also need a list of the outer hashkeys, as well as a list of the
-	 * hash operator OIDs.	Both lists of exprs must then be prepared for
-	 * execution.
+	 * Deconstruct the hash clauses into outer and inner argument values,
+	 * so that we can evaluate those subexpressions separately.  Also make
+	 * a list of the hash operator OIDs, in preparation for looking up the
+	 * hash functions to use.
 	 */
-	hjstate->hj_InnerHashKeys = (List *)
-		ExecInitExpr((Expr *) hashNode->hashkeys,
-					 innerPlanState(hjstate));
-	((HashState *) innerPlanState(hjstate))->hashkeys =
-		hjstate->hj_InnerHashKeys;
-
-	hclauses = NIL;
+	lclauses = NIL;
+	rclauses = NIL;
 	hoperators = NIL;
-	foreach(hcl, node->hashclauses)
+	foreach(hcl, hjstate->hashclauses)
 	{
-		OpExpr	   *hclause = (OpExpr *) lfirst(hcl);
+		FuncExprState *fstate = (FuncExprState *) lfirst(hcl);
+		OpExpr	   *hclause;
 
+		Assert(IsA(fstate, FuncExprState));
+		hclause = (OpExpr *) fstate->xprstate.expr;
 		Assert(IsA(hclause, OpExpr));
-		hclauses = lappend(hclauses, get_leftop((Expr *) hclause));
+		lclauses = lappend(lclauses, lfirst(fstate->args));
+		rclauses = lappend(rclauses, lsecond(fstate->args));
 		hoperators = lappendo(hoperators, hclause->opno);
 	}
-	hjstate->hj_OuterHashKeys = (List *)
-		ExecInitExpr((Expr *) hclauses,
-					 (PlanState *) hjstate);
+	hjstate->hj_OuterHashKeys = lclauses;
+	hjstate->hj_InnerHashKeys = rclauses;
 	hjstate->hj_HashOperators = hoperators;
+	/* child Hash node needs to evaluate inner hash keys, too */
+	((HashState *) innerPlanState(hjstate))->hashkeys = rclauses;
 
 	hjstate->js.ps.ps_OuterTupleSlot = NULL;
 	hjstate->js.ps.ps_TupFromTlist = false;
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 6cf8450567aa20e5567e64d996896d4b7502559a..54dc63654eb8ff923ebd47e2d75b9361830a9876 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.267 2003/11/12 21:15:52 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.268 2003/11/25 21:00:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -551,7 +551,6 @@ _copyHash(Hash *from)
 	/*
 	 * copy remainder of node
 	 */
-	COPY_NODE_FIELD(hashkeys);
 
 	return newnode;
 }
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index cb875bd6769c446da3ffaebb6cd1360573699d0f..b9dc382484e8e05be76c3cd7ad757195e7944bc0 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.220 2003/11/12 21:15:52 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.221 2003/11/25 21:00:53 tgl Exp $
  *
  * NOTES
  *	  Every node type that can appear in stored rules' parsetrees *must*
@@ -531,8 +531,6 @@ _outHash(StringInfo str, Hash *node)
 	WRITE_NODE_TYPE("HASH");
 
 	_outPlanInfo(str, (Plan *) node);
-
-	WRITE_NODE_FIELD(hashkeys);
 }
 
 /*****************************************************************************
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index a5efcb339e0a3f06f3efcd09e7b4affb2988a4c8..c455946ae38bebfacd7e85d0eb47602b2cb0efa1 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.159 2003/11/12 21:15:53 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.160 2003/11/25 21:00:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -97,7 +97,7 @@ static HashJoin *make_hashjoin(List *tlist,
 			  List *hashclauses,
 			  Plan *lefttree, Plan *righttree,
 			  JoinType jointype);
-static Hash *make_hash(List *tlist, List *hashkeys, Plan *lefttree);
+static Hash *make_hash(List *tlist, Plan *lefttree);
 static MergeJoin *make_mergejoin(List *tlist,
 			   List *joinclauses, List *otherclauses,
 			   List *mergeclauses,
@@ -1067,8 +1067,6 @@ create_hashjoin_plan(Query *root,
 	List	   *hashclauses;
 	HashJoin   *join_plan;
 	Hash	   *hash_plan;
-	List	   *innerhashkeys;
-	List	   *hcl;
 
 	/* Get the join qual clauses (in plain expression form) */
 	if (IS_OUTER_JOIN(best_path->jpath.jointype))
@@ -1102,14 +1100,6 @@ create_hashjoin_plan(Query *root,
 	otherclauses = order_qual_clauses(root, otherclauses);
 	hashclauses = order_qual_clauses(root, hashclauses);
 
-	/*
-	 * Extract the inner hash keys (right-hand operands of the
-	 * hashclauses) to put in the Hash node.
-	 */
-	innerhashkeys = NIL;
-	foreach(hcl, hashclauses)
-		innerhashkeys = lappend(innerhashkeys, get_rightop(lfirst(hcl)));
-
 	/* We don't want any excess columns in the hashed tuples */
 	disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
 
@@ -1117,7 +1107,6 @@ create_hashjoin_plan(Query *root,
 	 * Build the hash node and hash join node.
 	 */
 	hash_plan = make_hash(inner_plan->targetlist,
-						  innerhashkeys,
 						  inner_plan);
 	join_plan = make_hashjoin(tlist,
 							  joinclauses,
@@ -1728,7 +1717,7 @@ make_hashjoin(List *tlist,
 }
 
 static Hash *
-make_hash(List *tlist, List *hashkeys, Plan *lefttree)
+make_hash(List *tlist, Plan *lefttree)
 {
 	Hash	   *node = makeNode(Hash);
 	Plan	   *plan = &node->plan;
@@ -1744,7 +1733,6 @@ make_hash(List *tlist, List *hashkeys, Plan *lefttree)
 	plan->qual = NIL;
 	plan->lefttree = lefttree;
 	plan->righttree = NULL;
-	node->hashkeys = hashkeys;
 
 	return node;
 }
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index ec21c1a8d3be5819b2a93d7fdde0d3c60071b843..2952e8f0773b08c0e10e1b76e3f4113a2d2a4f46 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.97 2003/08/08 21:41:50 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.98 2003/11/25 21:00:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -167,24 +167,6 @@ set_plan_references(Plan *plan, List *rtable)
 							  (Node *) ((HashJoin *) plan)->hashclauses);
 			break;
 		case T_Hash:
-
-			/*
-			 * Hash does not evaluate its targetlist or quals, so don't
-			 * touch those (see comments below).  But we do need to fix
-			 * its hashkeys.  The hashkeys are a little bizarre because
-			 * they need to match the hashclauses of the parent HashJoin
-			 * node, so we use join_references to fix them.
-			 */
-			((Hash *) plan)->hashkeys =
-				join_references(((Hash *) plan)->hashkeys,
-								rtable,
-								NIL,
-								plan->lefttree->targetlist,
-								(Index) 0,
-					targetlist_has_non_vars(plan->lefttree->targetlist));
-			fix_expr_references(plan,
-								(Node *) ((Hash *) plan)->hashkeys);
-			break;
 		case T_Material:
 		case T_Sort:
 		case T_Unique:
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 11612f408c9817446b0afc3593ef588abd989a16..dab4cf3233afe8ebd4fb5cf91f47cfc44d8b52fa 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
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.83 2003/10/18 16:52:15 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.84 2003/11/25 21:00:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1013,10 +1013,6 @@ finalize_plan(Plan *plan, List *rtable,
 			break;
 
 		case T_Hash:
-			finalize_primnode((Node *) ((Hash *) plan)->hashkeys,
-							  &context);
-			break;
-
 		case T_Agg:
 		case T_SeqScan:
 		case T_Material:
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 669ce93e70a51ed9d9d95df2cd42b5bfbde0d497..6513bf35105f45738707ab50587cbd70205e1138 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: plannodes.h,v 1.70 2003/11/12 21:15:59 tgl Exp $
+ * $Id: plannodes.h,v 1.71 2003/11/25 21:00:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -350,7 +350,7 @@ typedef struct Unique
 typedef struct Hash
 {
 	Plan		plan;
-	List	   *hashkeys;
+	/* all other info is in the parent HashJoin node */
 } Hash;
 
 /* ----------------