diff options
Diffstat (limited to 'src/backend/executor/execTuples.c')
-rw-r--r-- | src/backend/executor/execTuples.c | 85 |
1 files changed, 50 insertions, 35 deletions
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 9f0d9daa829..391db672d1d 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -676,23 +676,27 @@ ExecCopySlotMinimalTuple(TupleTableSlot *slot) slot->tts_isnull); } -/* -------------------------------- - * ExecFetchSlotTuple - * Fetch the slot's regular physical tuple. - * - * If the slot contains a virtual tuple, we convert it to physical - * form. The slot retains ownership of the physical tuple. - * If it contains a minimal tuple we convert to regular form and store - * that in addition to the minimal tuple (not instead of, because - * callers may hold pointers to Datums within the minimal tuple). - * - * The main difference between this and ExecMaterializeSlot() is that this - * does not guarantee that the contained tuple is local storage. - * Hence, the result must be treated as read-only. - * -------------------------------- +/* + * ExecFetchSlotHeapTuple - fetch HeapTuple representing the slot's content + * + * The returned HeapTuple represents the slot's content as closely as + * possible. + * + * If materialize is true, the contents of the slots will be made independent + * from the underlying storage (i.e. all buffer pins are release, memory is + * allocated in the slot's context). + * + * If shouldFree is not-NULL it'll be set to true if the returned tuple has + * been allocated in the calling memory context, and must be freed by the + * caller (via explicit pfree() or a memory context reset). + * + * NB: If materialize is true, modifications of the returned tuple are + * allowed. But it depends on the type of the slot whether such modifications + * will also affect the slot's contents. While that is not the nicest + * behaviour, all such modifcations are in the process of being removed. */ HeapTuple -ExecFetchSlotTuple(TupleTableSlot *slot) +ExecFetchSlotHeapTuple(TupleTableSlot *slot, bool materialize, bool *shouldFree) { /* * sanity checks @@ -700,6 +704,10 @@ ExecFetchSlotTuple(TupleTableSlot *slot) Assert(slot != NULL); Assert(!TTS_EMPTY(slot)); + /* will be used in the near future */ + if (shouldFree) + *shouldFree = false; + /* * If we have a regular physical tuple then just return it. */ @@ -722,7 +730,9 @@ ExecFetchSlotTuple(TupleTableSlot *slot) /* * Otherwise materialize the slot... */ - return ExecMaterializeSlot(slot); + ExecMaterializeSlot(slot); + + return slot->tts_tuple; } /* -------------------------------- @@ -739,7 +749,7 @@ ExecFetchSlotTuple(TupleTableSlot *slot) * -------------------------------- */ MinimalTuple -ExecFetchSlotMinimalTuple(TupleTableSlot *slot) +ExecFetchSlotMinimalTuple(TupleTableSlot *slot, bool *shouldFree) { MemoryContext oldContext; @@ -749,6 +759,9 @@ ExecFetchSlotMinimalTuple(TupleTableSlot *slot) Assert(slot != NULL); Assert(!TTS_EMPTY(slot)); + /* will be used in the near future */ + if (shouldFree) + *shouldFree = false; /* * If we have a minimal physical tuple (local or not) then just return it. @@ -779,40 +792,44 @@ ExecFetchSlotMinimalTuple(TupleTableSlot *slot) } /* -------------------------------- - * ExecFetchSlotTupleDatum + * ExecFetchSlotHeapTupleDatum * Fetch the slot's tuple as a composite-type Datum. * * The result is always freshly palloc'd in the caller's memory context. * -------------------------------- */ Datum -ExecFetchSlotTupleDatum(TupleTableSlot *slot) +ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot) { HeapTuple tup; TupleDesc tupdesc; + bool shouldFree; + Datum ret; /* Fetch slot's contents in regular-physical-tuple form */ - tup = ExecFetchSlotTuple(slot); + tup = ExecFetchSlotHeapTuple(slot, false, &shouldFree); tupdesc = slot->tts_tupleDescriptor; /* Convert to Datum form */ - return heap_copy_tuple_as_datum(tup, tupdesc); + ret = heap_copy_tuple_as_datum(tup, tupdesc); + + if (shouldFree) + pfree(tup); + + return ret; } -/* -------------------------------- - * ExecMaterializeSlot - * Force a slot into the "materialized" state. +/* ExecMaterializeSlot - force a slot into the "materialized" state. * - * This causes the slot's tuple to be a local copy not dependent on - * any external storage. A pointer to the contained tuple is returned. + * This causes the slot's tuple to be a local copy not dependent on any + * external storage (i.e. pointing into a Buffer, or having allocations in + * another memory context). * - * A typical use for this operation is to prepare a computed tuple - * for being stored on disk. The original data may or may not be - * virtual, but in any case we need a private copy for heap_insert - * to scribble on. - * -------------------------------- + * A typical use for this operation is to prepare a computed tuple for being + * stored on disk. The original data may or may not be virtual, but in any + * case we need a private copy for heap_insert to scribble on. */ -HeapTuple +void ExecMaterializeSlot(TupleTableSlot *slot) { MemoryContext oldContext; @@ -828,7 +845,7 @@ ExecMaterializeSlot(TupleTableSlot *slot) * nothing to do. */ if (slot->tts_tuple && TTS_SHOULDFREE(slot)) - return slot->tts_tuple; + return; /* * Otherwise, copy or build a physical tuple, and store it into the slot. @@ -868,8 +885,6 @@ ExecMaterializeSlot(TupleTableSlot *slot) */ if (!TTS_SHOULDFREEMIN(slot)) slot->tts_mintuple = NULL; - - return slot->tts_tuple; } /* -------------------------------- |