*** a/src/backend/commands/prepare.c
--- b/src/backend/commands/prepare.c
***************
*** 779,785 **** pg_prepared_statement(PG_FUNCTION_ARGS)
  	 */
  	tupstore =
  		tuplestore_begin_heap(rsinfo->allowedModes & SFRM_Materialize_Random,
! 							  false, work_mem);
  
  	/* hash table might be uninitialized */
  	if (prepared_queries)
--- 779,785 ----
  	 */
  	tupstore =
  		tuplestore_begin_heap(rsinfo->allowedModes & SFRM_Materialize_Random,
! 							  false, work_mem, NULL);
  
  	/* hash table might be uninitialized */
  	if (prepared_queries)
*** a/src/backend/executor/execQual.c
--- b/src/backend/executor/execQual.c
***************
*** 1957,1963 **** ExecMakeTableFunctionResult(ExprState *funcexpr,
  									   -1,
  									   0);
  				}
! 				tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
  				MemoryContextSwitchTo(oldcontext);
  				rsinfo.setResult = tupstore;
  				rsinfo.setDesc = tupdesc;
--- 1957,1963 ----
  									   -1,
  									   0);
  				}
! 				tupstore = tuplestore_begin_heap(randomAccess, false, work_mem, NULL);
  				MemoryContextSwitchTo(oldcontext);
  				rsinfo.setResult = tupstore;
  				rsinfo.setDesc = tupdesc;
***************
*** 2024,2030 **** no_function_result:
  	if (rsinfo.setResult == NULL)
  	{
  		MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
! 		tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);
  		rsinfo.setResult = tupstore;
  		if (!returnsSet)
  		{
--- 2024,2030 ----
  	if (rsinfo.setResult == NULL)
  	{
  		MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
! 		tupstore = tuplestore_begin_heap(randomAccess, false, work_mem, NULL);
  		rsinfo.setResult = tupstore;
  		if (!returnsSet)
  		{
*** a/src/backend/executor/functions.c
--- b/src/backend/executor/functions.c
***************
*** 674,680 **** fmgr_sql(PG_FUNCTION_ARGS)
  	 * Note it's in the query-lifespan context.
  	 */
  	if (!fcache->tstore)
! 		fcache->tstore = tuplestore_begin_heap(randomAccess, false, work_mem);
  
  	/*
  	 * Find first unfinished query in function.
--- 674,680 ----
  	 * Note it's in the query-lifespan context.
  	 */
  	if (!fcache->tstore)
! 		fcache->tstore = tuplestore_begin_heap(randomAccess, false, work_mem, NULL);
  
  	/*
  	 * Find first unfinished query in function.
*** a/src/backend/executor/nodeCtescan.c
--- b/src/backend/executor/nodeCtescan.c
***************
*** 203,209 **** ExecInitCteScan(CteScan *node, EState *estate, int eflags)
  		/* I am the leader */
  		prmdata->value = PointerGetDatum(scanstate);
  		scanstate->leader = scanstate;
! 		scanstate->cte_table = tuplestore_begin_heap(true, false, work_mem);
  		tuplestore_set_eflags(scanstate->cte_table, scanstate->eflags);
  		scanstate->readptr = 0;
  	}
--- 203,209 ----
  		/* I am the leader */
  		prmdata->value = PointerGetDatum(scanstate);
  		scanstate->leader = scanstate;
! 		scanstate->cte_table = tuplestore_begin_heap(true, false, work_mem, scanstate->ss.ps.state->es_tupleTable);
  		tuplestore_set_eflags(scanstate->cte_table, scanstate->eflags);
  		scanstate->readptr = 0;
  	}
*** a/src/backend/executor/nodeMaterial.c
--- b/src/backend/executor/nodeMaterial.c
***************
*** 58,64 **** ExecMaterial(MaterialState *node)
  	 */
  	if (tuplestorestate == NULL && node->eflags != 0)
  	{
! 		tuplestorestate = tuplestore_begin_heap(true, false, work_mem);
  		tuplestore_set_eflags(tuplestorestate, node->eflags);
  		if (node->eflags & EXEC_FLAG_MARK)
  		{
--- 58,64 ----
  	 */
  	if (tuplestorestate == NULL && node->eflags != 0)
  	{
! 		tuplestorestate = tuplestore_begin_heap(true, false, work_mem, NULL);
  		tuplestore_set_eflags(tuplestorestate, node->eflags);
  		if (node->eflags & EXEC_FLAG_MARK)
  		{
*** a/src/backend/executor/nodeRecursiveunion.c
--- b/src/backend/executor/nodeRecursiveunion.c
***************
*** 127,133 **** ExecRecursiveUnion(RecursiveUnionState *node)
  
  			/* create new empty intermediate table */
  			node->intermediate_table = tuplestore_begin_heap(false, false,
! 															 work_mem);
  			node->intermediate_empty = true;
  
  			/* reset the recursive term */
--- 127,133 ----
  
  			/* create new empty intermediate table */
  			node->intermediate_table = tuplestore_begin_heap(false, false,
! 															 work_mem, NULL);
  			node->intermediate_empty = true;
  
  			/* reset the recursive term */
***************
*** 189,196 **** ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags)
  	/* initialize processing state */
  	rustate->recursing = false;
  	rustate->intermediate_empty = true;
! 	rustate->working_table = tuplestore_begin_heap(false, false, work_mem);
! 	rustate->intermediate_table = tuplestore_begin_heap(false, false, work_mem);
  
  	/*
  	 * If hashing, we need a per-tuple memory context for comparisons, and a
--- 189,196 ----
  	/* initialize processing state */
  	rustate->recursing = false;
  	rustate->intermediate_empty = true;
! 	rustate->working_table = tuplestore_begin_heap(false, false, work_mem, NULL);
! 	rustate->intermediate_table = tuplestore_begin_heap(false, false, work_mem, NULL);
  
  	/*
  	 * If hashing, we need a per-tuple memory context for comparisons, and a
*** a/src/backend/executor/nodeWindowAgg.c
--- b/src/backend/executor/nodeWindowAgg.c
***************
*** 651,657 **** begin_partition(WindowAggState *winstate)
  	}
  
  	/* Create new tuplestore for this partition */
! 	winstate->buffer = tuplestore_begin_heap(false, false, work_mem);
  
  	/*
  	 * Set up read pointers for the tuplestore.  The current and agg pointers
--- 651,658 ----
  	}
  
  	/* Create new tuplestore for this partition */
! 	winstate->buffer = tuplestore_begin_heap(false, false, work_mem,
! 							winstate->ss.ps.state->es_tupleTable);
  
  	/*
  	 * Set up read pointers for the tuplestore.  The current and agg pointers
*** a/src/backend/foreign/foreign.c
--- b/src/backend/foreign/foreign.c
***************
*** 291,297 **** deflist_to_tuplestore(ReturnSetInfo *rsinfo, List *options)
  	 * Now prepare the result set.
  	 */
  	tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);
! 	tupstore = tuplestore_begin_heap(true, false, work_mem);
  	rsinfo->returnMode = SFRM_Materialize;
  	rsinfo->setResult = tupstore;
  	rsinfo->setDesc = tupdesc;
--- 291,297 ----
  	 * Now prepare the result set.
  	 */
  	tupdesc = CreateTupleDescCopy(rsinfo->expectedDesc);
! 	tupstore = tuplestore_begin_heap(true, false, work_mem, NULL);
  	rsinfo->returnMode = SFRM_Materialize;
  	rsinfo->setResult = tupstore;
  	rsinfo->setDesc = tupdesc;
*** a/src/backend/utils/mmgr/portalmem.c
--- b/src/backend/utils/mmgr/portalmem.c
***************
*** 364,370 **** PortalCreateHoldStore(Portal portal)
  
  	portal->holdStore =
  		tuplestore_begin_heap(portal->cursorOptions & CURSOR_OPT_SCROLL,
! 							  true, work_mem);
  
  	MemoryContextSwitchTo(oldcxt);
  }
--- 364,370 ----
  
  	portal->holdStore =
  		tuplestore_begin_heap(portal->cursorOptions & CURSOR_OPT_SCROLL,
! 							  true, work_mem, NULL);
  
  	MemoryContextSwitchTo(oldcxt);
  }
***************
*** 921,927 **** pg_cursor(PG_FUNCTION_ARGS)
  	 */
  	tupstore =
  		tuplestore_begin_heap(rsinfo->allowedModes & SFRM_Materialize_Random,
! 							  false, work_mem);
  
  	hash_seq_init(&hash_seq, PortalHashTable);
  	while ((hentry = hash_seq_search(&hash_seq)) != NULL)
--- 921,927 ----
  	 */
  	tupstore =
  		tuplestore_begin_heap(rsinfo->allowedModes & SFRM_Materialize_Random,
! 							  false, work_mem, NULL);
  
  	hash_seq_init(&hash_seq, PortalHashTable);
  	while ((hentry = hash_seq_search(&hash_seq)) != NULL)
*** a/src/backend/utils/sort/tuplestore.c
--- b/src/backend/utils/sort/tuplestore.c
***************
*** 147,152 **** struct Tuplestorestate
--- 147,154 ----
  	int			memtupcount;	/* number of tuples currently present */
  	int			memtupsize;		/* allocated length of memtuples array */
  
+ 	TupleTable	tupleTable;
+ 
  	/*
  	 * These variables are used to keep track of the current positions.
  	 *
***************
*** 219,225 **** struct Tuplestorestate
  
  static Tuplestorestate *tuplestore_begin_common(int eflags,
  						bool interXact,
! 						int maxKBytes);
  static void tuplestore_puttuple_common(Tuplestorestate *state, void *tuple);
  static void dumptuples(Tuplestorestate *state);
  static unsigned int getlen(Tuplestorestate *state, bool eofOK);
--- 221,228 ----
  
  static Tuplestorestate *tuplestore_begin_common(int eflags,
  						bool interXact,
! 						int maxKBytes,
! 						TupleTable tupleTable);
  static void tuplestore_puttuple_common(Tuplestorestate *state, void *tuple);
  static void dumptuples(Tuplestorestate *state);
  static unsigned int getlen(Tuplestorestate *state, bool eofOK);
***************
*** 234,240 **** static void *readtup_heap(Tuplestorestate *state, unsigned int len);
   * Initialize for a tuple store operation.
   */
  static Tuplestorestate *
! tuplestore_begin_common(int eflags, bool interXact, int maxKBytes)
  {
  	Tuplestorestate *state;
  
--- 237,243 ----
   * Initialize for a tuple store operation.
   */
  static Tuplestorestate *
! tuplestore_begin_common(int eflags, bool interXact, int maxKBytes, TupleTable tupleTable)
  {
  	Tuplestorestate *state;
  
***************
*** 253,258 **** tuplestore_begin_common(int eflags, bool interXact, int maxKBytes)
--- 256,263 ----
  
  	USEMEM(state, GetMemoryChunkSpace(state->memtuples));
  
+ 	state->tupleTable = tupleTable;
+ 
  	state->activeptr = 0;
  	state->readptrcount = 1;
  	state->readptrsize = 8;		/* arbitrary */
***************
*** 286,292 **** tuplestore_begin_common(int eflags, bool interXact, int maxKBytes)
   * amount is paged to disk).  When in doubt, use work_mem.
   */
  Tuplestorestate *
! tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
  {
  	Tuplestorestate *state;
  	int			eflags;
--- 291,297 ----
   * amount is paged to disk).  When in doubt, use work_mem.
   */
  Tuplestorestate *
! tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes, TupleTable tupleTable)
  {
  	Tuplestorestate *state;
  	int			eflags;
***************
*** 299,305 **** tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
  		(EXEC_FLAG_BACKWARD | EXEC_FLAG_REWIND) :
  		(EXEC_FLAG_REWIND);
  
! 	state = tuplestore_begin_common(eflags, interXact, maxKBytes);
  
  	state->copytup = copytup_heap;
  	state->writetup = writetup_heap;
--- 304,310 ----
  		(EXEC_FLAG_BACKWARD | EXEC_FLAG_REWIND) :
  		(EXEC_FLAG_REWIND);
  
! 	state = tuplestore_begin_common(eflags, interXact, maxKBytes, tupleTable);
  
  	state->copytup = copytup_heap;
  	state->writetup = writetup_heap;
***************
*** 931,936 **** static void
--- 936,943 ----
  dumptuples(Tuplestorestate *state)
  {
  	int			i;
+ 	TupleTable	tupleTable = state->tupleTable;
+ 	
  
  	for (i = 0;; i++)
  	{
***************
*** 945,950 **** dumptuples(Tuplestorestate *state)
--- 952,968 ----
  		}
  		if (i >= state->memtupcount)
  			break;
+ 
+ 		if (tupleTable)
+ 		{
+ 			for (j = 0; j < tupleTable->size; j++)
+ 			{
+ 				if (tupleTable->array[j].tts_mintuple == state->memtuples[i])
+ 				{
+ 					ExecMaterializeSlot(&(tupleTable->array[j]));
+ 				}
+ 			}
+ 		}
  		WRITETUP(state, state->memtuples[i]);
  	}
  	state->memtupcount = 0;
*** a/src/include/utils/tuplestore.h
--- b/src/include/utils/tuplestore.h
***************
*** 46,52 **** typedef struct Tuplestorestate Tuplestorestate;
  
  extern Tuplestorestate *tuplestore_begin_heap(bool randomAccess,
  					  bool interXact,
! 					  int maxKBytes);
  
  extern void tuplestore_set_eflags(Tuplestorestate *state, int eflags);
  
--- 46,53 ----
  
  extern Tuplestorestate *tuplestore_begin_heap(bool randomAccess,
  					  bool interXact,
! 					  int maxKBytes,
! 					  TupleTable tupleTable);
  
  extern void tuplestore_set_eflags(Tuplestorestate *state, int eflags);
  
*** a/src/pl/plpgsql/src/pl_exec.c
--- b/src/pl/plpgsql/src/pl_exec.c
***************
*** 2355,2361 **** exec_init_tuple_store(PLpgSQL_execstate *estate)
  	oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
  	estate->tuple_store =
  		tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize_Random,
! 							  false, work_mem);
  	MemoryContextSwitchTo(oldcxt);
  
  	estate->rettupdesc = rsi->expectedDesc;
--- 2355,2361 ----
  	oldcxt = MemoryContextSwitchTo(estate->tuple_store_cxt);
  	estate->tuple_store =
  		tuplestore_begin_heap(rsi->allowedModes & SFRM_Materialize_Random,
! 							  false, work_mem, NULL);
  	MemoryContextSwitchTo(oldcxt);
  
  	estate->rettupdesc = rsi->expectedDesc;
