diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index 419f3f36bd2838c98082330a122e96416932833d..c02bd70d88901eff9ff9694c382c44ac7a86e3f9 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.102 2010/07/12 17:01:05 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.103 2010/07/28 04:50:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -89,7 +89,6 @@ ExecHashSubPlan(SubPlanState *node,
 {
 	SubPlan    *subplan = (SubPlan *) node->xprstate.expr;
 	PlanState  *planstate = node->planstate;
-	ExprContext *innerecontext = node->innerecontext;
 	TupleTableSlot *slot;
 
 	/* Shouldn't have any direct correlation Vars */
@@ -126,12 +125,6 @@ ExecHashSubPlan(SubPlanState *node,
 	 * it still needs to free the tuple.
 	 */
 
-	/*
-	 * Since the hashtable routines will use innerecontext's per-tuple memory
-	 * as working memory, be sure to reset it for each tuple.
-	 */
-	ResetExprContext(innerecontext);
-
 	/*
 	 * If the LHS is all non-null, probe for an exact match in the main hash
 	 * table.  If we find one, the result is TRUE. Otherwise, scan the
@@ -438,7 +431,6 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
 	PlanState  *planstate = node->planstate;
 	int			ncols = list_length(subplan->paramIds);
 	ExprContext *innerecontext = node->innerecontext;
-	MemoryContext tempcxt = innerecontext->ecxt_per_tuple_memory;
 	MemoryContext oldcontext;
 	int			nbuckets;
 	TupleTableSlot *slot;
@@ -460,7 +452,7 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
 	 * If it's not necessary to distinguish FALSE and UNKNOWN, then we don't
 	 * need to store subplan output rows that contain NULL.
 	 */
-	MemoryContextReset(node->tablecxt);
+	MemoryContextReset(node->hashtablecxt);
 	node->hashtable = NULL;
 	node->hashnulls = NULL;
 	node->havehashrows = false;
@@ -476,8 +468,8 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
 										  node->tab_hash_funcs,
 										  nbuckets,
 										  sizeof(TupleHashEntryData),
-										  node->tablecxt,
-										  tempcxt);
+										  node->hashtablecxt,
+										  node->hashtempcxt);
 
 	if (!subplan->unknownEqFalse)
 	{
@@ -495,8 +487,8 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
 											  node->tab_hash_funcs,
 											  nbuckets,
 											  sizeof(TupleHashEntryData),
-											  node->tablecxt,
-											  tempcxt);
+											  node->hashtablecxt,
+											  node->hashtempcxt);
 	}
 
 	/*
@@ -555,7 +547,7 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
 
 		/*
 		 * Reset innerecontext after each inner tuple to free any memory used
-		 * in hash computation or comparison routines.
+		 * during ExecProject.
 		 */
 		ResetExprContext(innerecontext);
 	}
@@ -680,7 +672,8 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
 	sstate->projRight = NULL;
 	sstate->hashtable = NULL;
 	sstate->hashnulls = NULL;
-	sstate->tablecxt = NULL;
+	sstate->hashtablecxt = NULL;
+	sstate->hashtempcxt = NULL;
 	sstate->innerecontext = NULL;
 	sstate->keyColIdx = NULL;
 	sstate->tab_hash_funcs = NULL;
@@ -730,12 +723,19 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
 		ListCell   *l;
 
 		/* We need a memory context to hold the hash table(s) */
-		sstate->tablecxt =
+		sstate->hashtablecxt =
 			AllocSetContextCreate(CurrentMemoryContext,
 								  "Subplan HashTable Context",
 								  ALLOCSET_DEFAULT_MINSIZE,
 								  ALLOCSET_DEFAULT_INITSIZE,
 								  ALLOCSET_DEFAULT_MAXSIZE);
+		/* and a small one for the hash tables to use as temp storage */
+		sstate->hashtempcxt =
+			AllocSetContextCreate(CurrentMemoryContext,
+								  "Subplan HashTable Temp Context",
+								  ALLOCSET_SMALL_MINSIZE,
+								  ALLOCSET_SMALL_INITSIZE,
+								  ALLOCSET_SMALL_MAXSIZE);
 		/* and a short-lived exprcontext for function evaluation */
 		sstate->innerecontext = CreateExprContext(estate);
 		/* Silly little array of column numbers 1..n */
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 6455eeaa603a64a06c0677010b298824ff1ce60e..6876ca0b8df4499fcdc721ded6cd81852f7ed447 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.219 2010/02/26 02:01:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.220 2010/07/28 04:50:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -699,8 +699,9 @@ typedef struct SubPlanState
 	TupleHashTable hashnulls;	/* hash table for rows with null(s) */
 	bool		havehashrows;	/* TRUE if hashtable is not empty */
 	bool		havenullrows;	/* TRUE if hashnulls is not empty */
-	MemoryContext tablecxt;		/* memory context containing tables */
-	ExprContext *innerecontext; /* working context for comparisons */
+	MemoryContext hashtablecxt;	/* memory context containing hash tables */
+	MemoryContext hashtempcxt;	/* temp memory context for hash tables */
+	ExprContext *innerecontext; /* econtext for computing inner tuples */
 	AttrNumber *keyColIdx;		/* control data for hash tables */
 	FmgrInfo   *tab_hash_funcs; /* hash functions for table datatype(s) */
 	FmgrInfo   *tab_eq_funcs;	/* equality functions for table datatype(s) */
diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out
index e839ad7f9647b1ffc9141a1bc71a1936089bb84d..7f8c05bc800c57d60661a9fb21503cde49101347 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -521,3 +521,12 @@ from
 -----
 (0 rows)
 
+--
+-- Test case for premature memory release during hashing of subplan output
+--
+select '1'::text in (select '1'::name union all select '1'::name);
+ ?column? 
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql
index f6657fa535c50d635326f1f576284a3d69930a06..9d13c39c8ab7f6baedc3bf545786888f4bf2b6e8 100644
--- a/src/test/regress/sql/subselect.sql
+++ b/src/test/regress/sql/subselect.sql
@@ -335,3 +335,9 @@ from
    from int8_tbl) sq0
   join
   int4_tbl i4 on dummy = i4.f1;
+
+--
+-- Test case for premature memory release during hashing of subplan output
+--
+
+select '1'::text in (select '1'::name union all select '1'::name);