ExecGather(PlanState *pstate)
{
GatherState *node = castNode(GatherState, pstate);
- TupleTableSlot *fslot = node->funnel_slot;
TupleTableSlot *slot;
ExprContext *econtext;
/*
* Reset per-tuple memory context to free any expression evaluation
- * storage allocated in the previous tuple cycle. This will also clear
- * any previous tuple returned by a TupleQueueReader; to make sure we
- * don't leave a dangling pointer around, clear the working slot first.
+ * storage allocated in the previous tuple cycle.
*/
- ExecClearTuple(fslot);
econtext = node->ps.ps_ExprContext;
ResetExprContext(econtext);
PlanState *outerPlan = outerPlanState(gatherstate);
TupleTableSlot *outerTupleSlot;
TupleTableSlot *fslot = gatherstate->funnel_slot;
- MemoryContext tupleContext = gatherstate->ps.ps_ExprContext->ecxt_per_tuple_memory;
HeapTuple tup;
while (gatherstate->nreaders > 0 || gatherstate->need_to_scan_locally)
if (gatherstate->nreaders > 0)
{
- MemoryContext oldContext;
-
- /* Run TupleQueueReaders in per-tuple context */
- oldContext = MemoryContextSwitchTo(tupleContext);
tup = gather_readnext(gatherstate);
- MemoryContextSwitchTo(oldContext);
if (HeapTupleIsValid(tup))
{
fslot, /* slot in which to store the tuple */
InvalidBuffer, /* buffer associated with this
* tuple */
- false); /* slot should not pfree tuple */
+ true); /* pfree tuple when done with it */
return fslot;
}
}
&tuple_buffer->done);
if (!HeapTupleIsValid(tuple))
break;
- tuple_buffer->tuple[i] = heap_copytuple(tuple);
+ tuple_buffer->tuple[i] = tuple;
tuple_buffer->nTuples++;
}
}
&tuple_buffer->done);
if (!HeapTupleIsValid(tup))
return false;
- tup = heap_copytuple(tup);
/*
* Attempt to read more tuples in nowait mode and store them in the
{
TupleQueueReader *reader;
HeapTuple tup;
- MemoryContext oldContext;
- MemoryContext tupleContext;
/* Check for async events, particularly messages from workers. */
CHECK_FOR_INTERRUPTS();
/* Attempt to read a tuple. */
reader = gm_state->reader[nreader - 1];
-
- /* Run TupleQueueReaders in per-tuple context */
- tupleContext = gm_state->ps.ps_ExprContext->ecxt_per_tuple_memory;
- oldContext = MemoryContextSwitchTo(tupleContext);
tup = TupleQueueReaderNext(reader, nowait, done);
- MemoryContextSwitchTo(oldContext);
return tup;
}
* is set to true when there are no remaining tuples and otherwise to false.
*
* The returned tuple, if any, is allocated in CurrentMemoryContext.
+ * Note that this routine must not leak memory! (We used to allow that,
+ * but not any more.)
*
* Even when shm_mq_receive() returns SHM_MQ_WOULD_BLOCK, this can still
* accumulate bytes from a partially-read message, so it's useful to call