*** 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;