#include "access/htup.h"#include "access/tupdesc.h"#include "storage/buf.h"

Go to the source code of this file.
| #define TTS_HAS_PHYSICAL_TUPLE | ( | slot | ) | ((slot)->tts_tuple != NULL && (slot)->tts_tuple != &((slot)->tts_minhdr)) |
Definition at line 132 of file tuptable.h.
Referenced by ExecCopySlotTuple(), and ExecFetchSlotTuple().
| #define TupIsNull | ( | slot | ) | ((slot) == NULL || (slot)->tts_isempty) |
Definition at line 138 of file tuptable.h.
Referenced by agg_fill_hash_table(), agg_retrieve_direct(), begin_partition(), buildSubPlanHash(), CteScanNext(), eval_windowaggregates(), EvalPlanQual(), ExecAppend(), execCurrentOf(), ExecDelete(), ExecGroup(), ExecHashJoin(), ExecHashJoinOuterGetTuple(), ExecLimit(), ExecLockRows(), ExecMaterial(), ExecMergeAppend(), ExecMergeJoin(), ExecModifyTable(), ExecNestLoop(), ExecPostprocessPlan(), ExecProcNode(), ExecRecursiveUnion(), ExecResult(), ExecScan(), ExecScanSubPlan(), ExecSetParamPlan(), ExecSort(), ExecUnique(), ExecUpdate(), ExecutePlan(), ForeignNext(), GetTupleForTrigger(), heap_compare_slots(), MJEvalInnerValues(), MJEvalOuterValues(), MultiExecHash(), print_slot(), setop_fill_hash_table(), setop_retrieve_direct(), and spool_tuples().
| typedef struct TupleTableSlot TupleTableSlot |
| TupleTableSlot* ExecAllocTableSlot | ( | List ** | tupleTable | ) |
Definition at line 143 of file execTuples.c.
References lappend(), and MakeTupleTableSlot().
Referenced by ExecInitExtraTupleSlot(), ExecInitResultTupleSlot(), and ExecInitScanTupleSlot().
{
TupleTableSlot *slot = MakeTupleTableSlot();
*tupleTable = lappend(*tupleTable, slot);
return slot;
}
| TupleTableSlot* ExecClearTuple | ( | TupleTableSlot * | slot | ) |
Definition at line 448 of file execTuples.c.
References Assert, BufferIsValid, heap_free_minimal_tuple(), heap_freetuple(), NULL, ReleaseBuffer(), TupleTableSlot::tts_buffer, TupleTableSlot::tts_isempty, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_shouldFree, TupleTableSlot::tts_shouldFreeMin, and TupleTableSlot::tts_tuple.
Referenced by begin_partition(), BitmapHeapNext(), buildSubPlanHash(), CteScanNext(), do_tup_output(), eval_windowaggregates(), ExecAppend(), ExecDelete(), ExecDropSingleTupleTableSlot(), ExecEndAgg(), ExecEndBitmapHeapScan(), ExecEndCteScan(), ExecEndForeignScan(), ExecEndFunctionScan(), ExecEndGroup(), ExecEndHashJoin(), ExecEndIndexOnlyScan(), ExecEndIndexScan(), ExecEndMaterial(), ExecEndMergeJoin(), ExecEndModifyTable(), ExecEndNestLoop(), ExecEndRecursiveUnion(), ExecEndResult(), ExecEndSeqScan(), ExecEndSetOp(), ExecEndSort(), ExecEndSubqueryScan(), ExecEndTidScan(), ExecEndUnique(), ExecEndValuesScan(), ExecEndWindowAgg(), ExecEndWorkTableScan(), ExecFilterJunk(), ExecHashJoinGetSavedTuple(), ExecHashSubPlan(), ExecMaterial(), ExecMergeAppend(), ExecProject(), ExecReScanCteScan(), ExecReScanFunctionScan(), ExecReScanGroup(), ExecReScanMaterial(), ExecReScanMergeJoin(), ExecReScanSetOp(), ExecReScanSort(), ExecReScanUnique(), ExecReScanValuesScan(), ExecReScanWindowAgg(), ExecReScanWorkTableScan(), ExecResetTupleTable(), ExecScan(), ExecScanFetch(), ExecSeqRestrPos(), ExecSetSlotDescriptor(), ExecStoreAllNullTuple(), ExecUnique(), fileIterateForeignScan(), IndexNext(), IndexOnlyNext(), per_MultiFuncCall(), postgresIterateForeignScan(), process_ordered_aggregate_multi(), RunFromStore(), SeqNext(), setop_retrieve_direct(), setop_retrieve_hash_table(), ShutdownFuncExpr(), StoreIndexTuple(), TidNext(), tuplesort_gettupleslot(), tuplestore_gettupleslot(), ValuesNext(), and WinRowsArePeers().
{
/*
* sanity checks
*/
Assert(slot != NULL);
/*
* Free the old physical tuple if necessary.
*/
if (slot->tts_shouldFree)
heap_freetuple(slot->tts_tuple);
if (slot->tts_shouldFreeMin)
heap_free_minimal_tuple(slot->tts_mintuple);
slot->tts_tuple = NULL;
slot->tts_mintuple = NULL;
slot->tts_shouldFree = false;
slot->tts_shouldFreeMin = false;
/*
* Drop the pin on the referenced buffer, if there is one.
*/
if (BufferIsValid(slot->tts_buffer))
ReleaseBuffer(slot->tts_buffer);
slot->tts_buffer = InvalidBuffer;
/*
* Mark it empty.
*/
slot->tts_isempty = true;
slot->tts_nvalid = 0;
return slot;
}
| TupleTableSlot* ExecCopySlot | ( | TupleTableSlot * | dstslot, | |
| TupleTableSlot * | srcslot | |||
| ) |
Definition at line 810 of file execTuples.c.
References ExecCopySlotTuple(), ExecStoreTuple(), InvalidBuffer, MemoryContextSwitchTo(), and TupleTableSlot::tts_mcxt.
Referenced by begin_partition(), CteScanNext(), ExecGroup(), ExecUnique(), and spool_tuples().
{
HeapTuple newTuple;
MemoryContext oldContext;
/*
* There might be ways to optimize this when the source is virtual, but
* for now just always build a physical copy. Make sure it is in the
* right context.
*/
oldContext = MemoryContextSwitchTo(dstslot->tts_mcxt);
newTuple = ExecCopySlotTuple(srcslot);
MemoryContextSwitchTo(oldContext);
return ExecStoreTuple(newTuple, dstslot, InvalidBuffer, true);
}
| MinimalTuple ExecCopySlotMinimalTuple | ( | TupleTableSlot * | slot | ) |
Definition at line 586 of file execTuples.c.
References Assert, heap_copy_minimal_tuple(), heap_form_minimal_tuple(), minimal_tuple_from_heap_tuple(), NULL, TupleTableSlot::tts_isempty, TupleTableSlot::tts_isnull, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.
Referenced by copytup_heap(), ExecFetchSlotMinimalTuple(), LookupTupleHashEntry(), and tuplestore_puttupleslot().
{
/*
* sanity checks
*/
Assert(slot != NULL);
Assert(!slot->tts_isempty);
/*
* If we have a physical tuple then just copy it. Prefer to copy
* tts_mintuple since that's a tad cheaper.
*/
if (slot->tts_mintuple)
return heap_copy_minimal_tuple(slot->tts_mintuple);
if (slot->tts_tuple)
return minimal_tuple_from_heap_tuple(slot->tts_tuple);
/*
* Otherwise we need to build a tuple from the Datum array.
*/
return heap_form_minimal_tuple(slot->tts_tupleDescriptor,
slot->tts_values,
slot->tts_isnull);
}
| HeapTuple ExecCopySlotTuple | ( | TupleTableSlot * | slot | ) |
Definition at line 554 of file execTuples.c.
References Assert, heap_copytuple(), heap_form_tuple(), heap_tuple_from_minimal_tuple(), NULL, TTS_HAS_PHYSICAL_TUPLE, TupleTableSlot::tts_isempty, TupleTableSlot::tts_isnull, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.
Referenced by agg_retrieve_direct(), ExecCopySlot(), ExecMaterializeSlot(), ExecScanSubPlan(), ExecSetParamPlan(), setop_retrieve_direct(), and spi_printtup().
{
/*
* sanity checks
*/
Assert(slot != NULL);
Assert(!slot->tts_isempty);
/*
* If we have a physical tuple (either format) then just copy it.
*/
if (TTS_HAS_PHYSICAL_TUPLE(slot))
return heap_copytuple(slot->tts_tuple);
if (slot->tts_mintuple)
return heap_tuple_from_minimal_tuple(slot->tts_mintuple);
/*
* Otherwise we need to build a tuple from the Datum array.
*/
return heap_form_tuple(slot->tts_tupleDescriptor,
slot->tts_values,
slot->tts_isnull);
}
| void ExecDropSingleTupleTableSlot | ( | TupleTableSlot * | slot | ) |
Definition at line 225 of file execTuples.c.
References Assert, ExecClearTuple(), IsA, pfree(), ReleaseTupleDesc, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.
Referenced by ATRewriteTable(), CatalogIndexInsert(), check_exclusion_constraint(), compute_index_stats(), end_tup_output(), get_actual_variable_range(), IndexBuildHeapScan(), IndexCheckExclusion(), RunFromStore(), tuplesort_end(), validate_index_heapscan(), and validateCheckConstraint().
{
/* This should match ExecResetTupleTable's processing of one slot */
Assert(IsA(slot, TupleTableSlot));
ExecClearTuple(slot);
if (slot->tts_tupleDescriptor)
ReleaseTupleDesc(slot->tts_tupleDescriptor);
if (slot->tts_values)
pfree(slot->tts_values);
if (slot->tts_isnull)
pfree(slot->tts_isnull);
pfree(slot);
}
| MinimalTuple ExecFetchSlotMinimalTuple | ( | TupleTableSlot * | slot | ) |
Definition at line 661 of file execTuples.c.
References Assert, ExecCopySlotMinimalTuple(), MemoryContextSwitchTo(), NULL, TupleTableSlot::tts_isempty, TupleTableSlot::tts_mcxt, TupleTableSlot::tts_mintuple, and TupleTableSlot::tts_shouldFreeMin.
Referenced by ExecHashJoin(), ExecHashSkewTableInsert(), and ExecHashTableInsert().
{
MemoryContext oldContext;
/*
* sanity checks
*/
Assert(slot != NULL);
Assert(!slot->tts_isempty);
/*
* If we have a minimal physical tuple (local or not) then just return it.
*/
if (slot->tts_mintuple)
return slot->tts_mintuple;
/*
* Otherwise, copy or build a minimal tuple, and store it into the slot.
*
* We may be called in a context that is shorter-lived than the tuple
* slot, but we have to ensure that the materialized tuple will survive
* anyway.
*/
oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
slot->tts_mintuple = ExecCopySlotMinimalTuple(slot);
slot->tts_shouldFreeMin = true;
MemoryContextSwitchTo(oldContext);
/*
* Note: we may now have a situation where we have a local minimal tuple
* attached to a virtual or non-local physical tuple. There seems no harm
* in that at the moment, but if any materializes, we should change this
* function to force the slot into minimal-tuple-only state.
*/
return slot->tts_mintuple;
}
| HeapTuple ExecFetchSlotTuple | ( | TupleTableSlot * | slot | ) |
Definition at line 627 of file execTuples.c.
References Assert, ExecMaterializeSlot(), NULL, TTS_HAS_PHYSICAL_TUPLE, TupleTableSlot::tts_isempty, and TupleTableSlot::tts_tuple.
Referenced by ExecEvalWholeRowFast(), and ExecEvalWholeRowSlow().
{
/*
* sanity checks
*/
Assert(slot != NULL);
Assert(!slot->tts_isempty);
/*
* If we have a regular physical tuple then just return it.
*/
if (TTS_HAS_PHYSICAL_TUPLE(slot))
return slot->tts_tuple;
/*
* Otherwise materialize the slot...
*/
return ExecMaterializeSlot(slot);
}
| Datum ExecFetchSlotTupleDatum | ( | TupleTableSlot * | slot | ) |
Definition at line 709 of file execTuples.c.
References ExecMaterializeSlot(), HeapTupleHeaderSetDatumLength, HeapTupleHeaderSetTypeId, HeapTupleHeaderSetTypMod, PointerGetDatum, HeapTupleData::t_data, HeapTupleData::t_len, tupleDesc::tdtypeid, tupleDesc::tdtypmod, and TupleTableSlot::tts_tupleDescriptor.
Referenced by ExecMakeFunctionResult(), and postquel_get_single_result().
{
HeapTuple tup;
HeapTupleHeader td;
TupleDesc tupdesc;
/* Make sure we can scribble on the slot contents ... */
tup = ExecMaterializeSlot(slot);
/* ... and set up the composite-Datum header fields, in case not done */
td = tup->t_data;
tupdesc = slot->tts_tupleDescriptor;
HeapTupleHeaderSetDatumLength(td, tup->t_len);
HeapTupleHeaderSetTypeId(td, tupdesc->tdtypeid);
HeapTupleHeaderSetTypMod(td, tupdesc->tdtypmod);
return PointerGetDatum(td);
}
| HeapTuple ExecMaterializeSlot | ( | TupleTableSlot * | slot | ) |
Definition at line 740 of file execTuples.c.
References Assert, BufferIsValid, ExecCopySlotTuple(), MemoryContextSwitchTo(), NULL, ReleaseBuffer(), TupleTableSlot::tts_buffer, TupleTableSlot::tts_isempty, TupleTableSlot::tts_mcxt, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_shouldFree, TupleTableSlot::tts_shouldFreeMin, and TupleTableSlot::tts_tuple.
Referenced by CopyFrom(), EvalPlanQual(), ExecBRInsertTriggers(), ExecBRUpdateTriggers(), ExecDelete(), ExecFetchSlotTuple(), ExecFetchSlotTupleDatum(), ExecInsert(), ExecIRInsertTriggers(), ExecIRUpdateTriggers(), ExecUpdate(), ForeignNext(), intorel_receive(), and transientrel_receive().
{
MemoryContext oldContext;
/*
* sanity checks
*/
Assert(slot != NULL);
Assert(!slot->tts_isempty);
/*
* If we have a regular physical tuple, and it's locally palloc'd, we have
* nothing to do.
*/
if (slot->tts_tuple && slot->tts_shouldFree)
return slot->tts_tuple;
/*
* Otherwise, copy or build a physical tuple, and store it into the slot.
*
* We may be called in a context that is shorter-lived than the tuple
* slot, but we have to ensure that the materialized tuple will survive
* anyway.
*/
oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
slot->tts_tuple = ExecCopySlotTuple(slot);
slot->tts_shouldFree = true;
MemoryContextSwitchTo(oldContext);
/*
* Drop the pin on the referenced buffer, if there is one.
*/
if (BufferIsValid(slot->tts_buffer))
ReleaseBuffer(slot->tts_buffer);
slot->tts_buffer = InvalidBuffer;
/*
* Mark extracted state invalid. This is important because the slot is
* not supposed to depend any more on the previous external data; we
* mustn't leave any dangling pass-by-reference datums in tts_values.
* However, we have not actually invalidated any such datums, if there
* happen to be any previously fetched from the slot. (Note in particular
* that we have not pfree'd tts_mintuple, if there is one.)
*/
slot->tts_nvalid = 0;
/*
* On the same principle of not depending on previous remote storage,
* forget the mintuple if it's not local storage. (If it is local
* storage, we must not pfree it now, since callers might have already
* fetched datum pointers referencing it.)
*/
if (!slot->tts_shouldFreeMin)
slot->tts_mintuple = NULL;
return slot->tts_tuple;
}
Definition at line 162 of file execTuples.c.
References Assert, ExecClearTuple(), IsA, lfirst, list_free(), pfree(), ReleaseTupleDesc, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.
Referenced by CopyFrom(), EvalPlanQualEnd(), and ExecEndPlan().
{
ListCell *lc;
foreach(lc, tupleTable)
{
TupleTableSlot *slot = (TupleTableSlot *) lfirst(lc);
/* Sanity checks */
Assert(IsA(slot, TupleTableSlot));
/* Always release resources and reset the slot to empty */
ExecClearTuple(slot);
if (slot->tts_tupleDescriptor)
{
ReleaseTupleDesc(slot->tts_tupleDescriptor);
slot->tts_tupleDescriptor = NULL;
}
/* If shouldFree, release memory occupied by the slot itself */
if (shouldFree)
{
if (slot->tts_values)
pfree(slot->tts_values);
if (slot->tts_isnull)
pfree(slot->tts_isnull);
pfree(slot);
}
}
/* If shouldFree, release the list structure */
if (shouldFree)
list_free(tupleTable);
}
| void ExecSetSlotDescriptor | ( | TupleTableSlot * | slot, | |
| TupleDesc | tupdesc | |||
| ) |
Definition at line 256 of file execTuples.c.
References ExecClearTuple(), MemoryContextAlloc(), tupleDesc::natts, pfree(), PinTupleDesc, ReleaseTupleDesc, TupleTableSlot::tts_isnull, TupleTableSlot::tts_mcxt, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.
Referenced by CopyFrom(), ExecAssignResultType(), ExecAssignScanType(), ExecBRInsertTriggers(), ExecBRUpdateTriggers(), ExecDelete(), ExecInitAgg(), ExecInitHashJoin(), ExecInitJunkFilter(), ExecInitJunkFilterConversion(), ExecInitMergeJoin(), ExecInitNullTupleSlot(), ExecInitSubPlan(), ExecInitWindowAgg(), ExecIRInsertTriggers(), ExecIRUpdateTriggers(), lookup_hash_entry(), MakeSingleTupleTableSlot(), and TriggerEnabled().
{
/* For safety, make sure slot is empty before changing it */
ExecClearTuple(slot);
/*
* Release any old descriptor. Also release old Datum/isnull arrays if
* present (we don't bother to check if they could be re-used).
*/
if (slot->tts_tupleDescriptor)
ReleaseTupleDesc(slot->tts_tupleDescriptor);
if (slot->tts_values)
pfree(slot->tts_values);
if (slot->tts_isnull)
pfree(slot->tts_isnull);
/*
* Install the new descriptor; if it's refcounted, bump its refcount.
*/
slot->tts_tupleDescriptor = tupdesc;
PinTupleDesc(tupdesc);
/*
* Allocate Datum/isnull arrays of the appropriate size. These must have
* the same lifetime as the slot, so allocate in the slot's own context.
*/
slot->tts_values = (Datum *)
MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(Datum));
slot->tts_isnull = (bool *)
MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(bool));
}
| TupleTableSlot* ExecStoreAllNullTuple | ( | TupleTableSlot * | slot | ) |
Definition at line 521 of file execTuples.c.
References Assert, ExecClearTuple(), ExecStoreVirtualTuple(), MemSet, tupleDesc::natts, NULL, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.
Referenced by ExecInitNullTupleSlot(), and lookup_hash_entry().
{
/*
* sanity checks
*/
Assert(slot != NULL);
Assert(slot->tts_tupleDescriptor != NULL);
/* Clear any old contents */
ExecClearTuple(slot);
/*
* Fill all the columns of the virtual tuple with nulls
*/
MemSet(slot->tts_values, 0,
slot->tts_tupleDescriptor->natts * sizeof(Datum));
memset(slot->tts_isnull, true,
slot->tts_tupleDescriptor->natts * sizeof(bool));
return ExecStoreVirtualTuple(slot);
}
| TupleTableSlot* ExecStoreMinimalTuple | ( | MinimalTuple | mtup, | |
| TupleTableSlot * | slot, | |||
| bool | shouldFree | |||
| ) |
Definition at line 393 of file execTuples.c.
References Assert, BufferIsValid, heap_free_minimal_tuple(), heap_freetuple(), NULL, ReleaseBuffer(), HeapTupleData::t_data, MinimalTupleData::t_len, HeapTupleData::t_len, TupleTableSlot::tts_buffer, TupleTableSlot::tts_isempty, TupleTableSlot::tts_minhdr, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_shouldFree, TupleTableSlot::tts_shouldFreeMin, TupleTableSlot::tts_tuple, and TupleTableSlot::tts_tupleDescriptor.
Referenced by agg_retrieve_hash_table(), ExecHashJoinGetSavedTuple(), ExecScanHashBucket(), ExecScanHashTableForUnmatched(), findPartialMatch(), setop_retrieve_hash_table(), TupleHashTableHash(), TupleHashTableMatch(), tuplesort_gettupleslot(), and tuplestore_gettupleslot().
{
/*
* sanity checks
*/
Assert(mtup != NULL);
Assert(slot != NULL);
Assert(slot->tts_tupleDescriptor != NULL);
/*
* Free any old physical tuple belonging to the slot.
*/
if (slot->tts_shouldFree)
heap_freetuple(slot->tts_tuple);
if (slot->tts_shouldFreeMin)
heap_free_minimal_tuple(slot->tts_mintuple);
/*
* Drop the pin on the referenced buffer, if there is one.
*/
if (BufferIsValid(slot->tts_buffer))
ReleaseBuffer(slot->tts_buffer);
slot->tts_buffer = InvalidBuffer;
/*
* Store the new tuple into the specified slot.
*/
slot->tts_isempty = false;
slot->tts_shouldFree = false;
slot->tts_shouldFreeMin = shouldFree;
slot->tts_tuple = &slot->tts_minhdr;
slot->tts_mintuple = mtup;
slot->tts_minhdr.t_len = mtup->t_len + MINIMAL_TUPLE_OFFSET;
slot->tts_minhdr.t_data = (HeapTupleHeader) ((char *) mtup - MINIMAL_TUPLE_OFFSET);
/* no need to set t_self or t_tableOid since we won't allow access */
/* Mark extracted state invalid */
slot->tts_nvalid = 0;
return slot;
}
| TupleTableSlot* ExecStoreTuple | ( | HeapTuple | tuple, | |
| TupleTableSlot * | slot, | |||
| Buffer | buffer, | |||
| bool | shouldFree | |||
| ) |
Definition at line 329 of file execTuples.c.
References Assert, BufferIsValid, heap_free_minimal_tuple(), heap_freetuple(), IncrBufferRefCount(), NULL, ReleaseBuffer(), TupleTableSlot::tts_buffer, TupleTableSlot::tts_isempty, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_shouldFree, TupleTableSlot::tts_shouldFreeMin, TupleTableSlot::tts_tuple, and TupleTableSlot::tts_tupleDescriptor.
Referenced by agg_retrieve_direct(), ATRewriteTable(), BitmapHeapNext(), CatalogIndexInsert(), check_exclusion_constraint(), comparetup_cluster(), compute_index_stats(), CopyFrom(), CopyFromInsertBatch(), ExecBRInsertTriggers(), ExecBRUpdateTriggers(), ExecCopySlot(), ExecDelete(), ExecIRInsertTriggers(), ExecIRUpdateTriggers(), ExecScanFetch(), get_actual_variable_range(), IndexBuildHeapScan(), IndexCheckExclusion(), IndexNext(), postgresIterateForeignScan(), SeqNext(), setop_retrieve_direct(), store_returning_result(), TidNext(), TriggerEnabled(), validate_index_heapscan(), and validateCheckConstraint().
{
/*
* sanity checks
*/
Assert(tuple != NULL);
Assert(slot != NULL);
Assert(slot->tts_tupleDescriptor != NULL);
/* passing shouldFree=true for a tuple on a disk page is not sane */
Assert(BufferIsValid(buffer) ? (!shouldFree) : true);
/*
* Free any old physical tuple belonging to the slot.
*/
if (slot->tts_shouldFree)
heap_freetuple(slot->tts_tuple);
if (slot->tts_shouldFreeMin)
heap_free_minimal_tuple(slot->tts_mintuple);
/*
* Store the new tuple into the specified slot.
*/
slot->tts_isempty = false;
slot->tts_shouldFree = shouldFree;
slot->tts_shouldFreeMin = false;
slot->tts_tuple = tuple;
slot->tts_mintuple = NULL;
/* Mark extracted state invalid */
slot->tts_nvalid = 0;
/*
* If tuple is on a disk page, keep the page pinned as long as we hold a
* pointer into it. We assume the caller already has such a pin.
*
* This is coded to optimize the case where the slot previously held a
* tuple on the same disk page: in that case releasing and re-acquiring
* the pin is a waste of cycles. This is a common situation during
* seqscans, so it's worth troubling over.
*/
if (slot->tts_buffer != buffer)
{
if (BufferIsValid(slot->tts_buffer))
ReleaseBuffer(slot->tts_buffer);
slot->tts_buffer = buffer;
if (BufferIsValid(buffer))
IncrBufferRefCount(buffer);
}
return slot;
}
| TupleTableSlot* ExecStoreVirtualTuple | ( | TupleTableSlot * | slot | ) |
Definition at line 497 of file execTuples.c.
References Assert, tupleDesc::natts, NULL, TupleTableSlot::tts_isempty, TupleTableSlot::tts_nvalid, and TupleTableSlot::tts_tupleDescriptor.
Referenced by do_tup_output(), ExecFilterJunk(), ExecProject(), ExecStoreAllNullTuple(), fileIterateForeignScan(), StoreIndexTuple(), and ValuesNext().
{
/*
* sanity checks
*/
Assert(slot != NULL);
Assert(slot->tts_tupleDescriptor != NULL);
Assert(slot->tts_isempty);
slot->tts_isempty = false;
slot->tts_nvalid = slot->tts_tupleDescriptor->natts;
return slot;
}
| TupleTableSlot* MakeSingleTupleTableSlot | ( | TupleDesc | tupdesc | ) |
Definition at line 208 of file execTuples.c.
References ExecSetSlotDescriptor(), and MakeTupleTableSlot().
Referenced by ATRewriteTable(), begin_tup_output_tupdesc(), CatalogIndexInsert(), check_exclusion_constraint(), compute_index_stats(), ExecInitJunkFilter(), ExecInitJunkFilterConversion(), ExecPrepareTuplestoreResult(), get_actual_variable_range(), IndexBuildHeapScan(), IndexCheckExclusion(), LookupTupleHashEntry(), RunFromStore(), TupleDescGetSlot(), tuplesort_begin_cluster(), validate_index_heapscan(), and validateCheckConstraint().
{
TupleTableSlot *slot = MakeTupleTableSlot();
ExecSetSlotDescriptor(slot, tupdesc);
return slot;
}
| TupleTableSlot* MakeTupleTableSlot | ( | void | ) |
Definition at line 117 of file execTuples.c.
References CurrentMemoryContext, makeNode, TupleTableSlot::tts_buffer, TupleTableSlot::tts_isempty, TupleTableSlot::tts_isnull, TupleTableSlot::tts_mcxt, TupleTableSlot::tts_mintuple, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_shouldFree, TupleTableSlot::tts_shouldFreeMin, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.
Referenced by ExecAllocTableSlot(), and MakeSingleTupleTableSlot().
{
TupleTableSlot *slot = makeNode(TupleTableSlot);
slot->tts_isempty = true;
slot->tts_shouldFree = false;
slot->tts_shouldFreeMin = false;
slot->tts_tuple = NULL;
slot->tts_tupleDescriptor = NULL;
slot->tts_mcxt = CurrentMemoryContext;
slot->tts_buffer = InvalidBuffer;
slot->tts_nvalid = 0;
slot->tts_values = NULL;
slot->tts_isnull = NULL;
slot->tts_mintuple = NULL;
return slot;
}
| bool slot_attisnull | ( | TupleTableSlot * | slot, | |
| int | attnum | |||
| ) |
Definition at line 1321 of file heaptuple.c.
References elog, ERROR, heap_attisnull(), tupleDesc::natts, NULL, TupleTableSlot::tts_isnull, TupleTableSlot::tts_minhdr, TupleTableSlot::tts_tuple, and TupleTableSlot::tts_tupleDescriptor.
Referenced by ExecConstraints(), slotAllNulls(), and slotNoNulls().
{
HeapTuple tuple = slot->tts_tuple;
TupleDesc tupleDesc = slot->tts_tupleDescriptor;
/*
* system attributes are handled by heap_attisnull
*/
if (attnum <= 0)
{
if (tuple == NULL) /* internal error */
elog(ERROR, "cannot extract system attribute from virtual tuple");
if (tuple == &(slot->tts_minhdr)) /* internal error */
elog(ERROR, "cannot extract system attribute from minimal tuple");
return heap_attisnull(tuple, attnum);
}
/*
* fast path if desired attribute already cached
*/
if (attnum <= slot->tts_nvalid)
return slot->tts_isnull[attnum - 1];
/*
* return NULL if attnum is out of range according to the tupdesc
*/
if (attnum > tupleDesc->natts)
return true;
/*
* otherwise we had better have a physical tuple (tts_nvalid should equal
* natts in all virtual-tuple cases)
*/
if (tuple == NULL) /* internal error */
elog(ERROR, "cannot extract attribute from empty tuple slot");
/* and let the tuple tell it */
return heap_attisnull(tuple, attnum);
}
| void slot_getallattrs | ( | TupleTableSlot * | slot | ) |
Definition at line 1230 of file heaptuple.c.
References elog, ERROR, HeapTupleHeaderGetNatts, Min, tupleDesc::natts, NULL, slot_deform_tuple(), HeapTupleData::t_data, TupleTableSlot::tts_isnull, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.
Referenced by copy_dest_receive(), ExecBuildSlotValueDescription(), ExecFilterJunk(), printtup(), printtup_20(), printtup_internal_20(), and tstoreReceiveSlot_detoast().
{
int tdesc_natts = slot->tts_tupleDescriptor->natts;
int attnum;
HeapTuple tuple;
/* Quick out if we have 'em all already */
if (slot->tts_nvalid == tdesc_natts)
return;
/*
* otherwise we had better have a physical tuple (tts_nvalid should equal
* natts in all virtual-tuple cases)
*/
tuple = slot->tts_tuple;
if (tuple == NULL) /* internal error */
elog(ERROR, "cannot extract attribute from empty tuple slot");
/*
* load up any slots available from physical tuple
*/
attnum = HeapTupleHeaderGetNatts(tuple->t_data);
attnum = Min(attnum, tdesc_natts);
slot_deform_tuple(slot, attnum);
/*
* If tuple doesn't have all the atts indicated by tupleDesc, read the
* rest as null
*/
for (; attnum < tdesc_natts; attnum++)
{
slot->tts_values[attnum] = (Datum) 0;
slot->tts_isnull[attnum] = true;
}
slot->tts_nvalid = tdesc_natts;
}
| Datum slot_getattr | ( | TupleTableSlot * | slot, | |
| int | attnum, | |||
| bool * | isnull | |||
| ) |
Definition at line 1134 of file heaptuple.c.
References att_isnull, tupleDesc::attrs, elog, ERROR, heap_getsysattr(), HeapTupleHasNulls, HeapTupleHeaderGetNatts, tupleDesc::natts, NULL, slot_deform_tuple(), HeapTupleHeaderData::t_bits, HeapTupleData::t_data, TupleTableSlot::tts_isnull, TupleTableSlot::tts_minhdr, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.
Referenced by buildSubPlanHash(), convert_prep_stmt_params(), debugtup(), execCurrentOf(), ExecEvalScalarVar(), ExecEvalScalarVarFast(), ExecGetJunkAttribute(), ExecMakeFunctionResult(), ExecNestLoop(), ExecScanSubPlan(), ExecSetParamPlan(), execTuplesMatch(), execTuplesUnequal(), fetch_tuple_flag(), FormIndexDatum(), heap_compare_slots(), postquel_get_single_result(), and TupleHashTableHash().
{
HeapTuple tuple = slot->tts_tuple;
TupleDesc tupleDesc = slot->tts_tupleDescriptor;
HeapTupleHeader tup;
/*
* system attributes are handled by heap_getsysattr
*/
if (attnum <= 0)
{
if (tuple == NULL) /* internal error */
elog(ERROR, "cannot extract system attribute from virtual tuple");
if (tuple == &(slot->tts_minhdr)) /* internal error */
elog(ERROR, "cannot extract system attribute from minimal tuple");
return heap_getsysattr(tuple, attnum, tupleDesc, isnull);
}
/*
* fast path if desired attribute already cached
*/
if (attnum <= slot->tts_nvalid)
{
*isnull = slot->tts_isnull[attnum - 1];
return slot->tts_values[attnum - 1];
}
/*
* return NULL if attnum is out of range according to the tupdesc
*/
if (attnum > tupleDesc->natts)
{
*isnull = true;
return (Datum) 0;
}
/*
* otherwise we had better have a physical tuple (tts_nvalid should equal
* natts in all virtual-tuple cases)
*/
if (tuple == NULL) /* internal error */
elog(ERROR, "cannot extract attribute from empty tuple slot");
/*
* return NULL if attnum is out of range according to the tuple
*
* (We have to check this separately because of various inheritance and
* table-alteration scenarios: the tuple could be either longer or shorter
* than the tupdesc.)
*/
tup = tuple->t_data;
if (attnum > HeapTupleHeaderGetNatts(tup))
{
*isnull = true;
return (Datum) 0;
}
/*
* check if target attribute is null: no point in groveling through tuple
*/
if (HeapTupleHasNulls(tuple) && att_isnull(attnum - 1, tup->t_bits))
{
*isnull = true;
return (Datum) 0;
}
/*
* If the attribute's column has been dropped, we force a NULL result.
* This case should not happen in normal use, but it could happen if we
* are executing a plan cached before the column was dropped.
*/
if (tupleDesc->attrs[attnum - 1]->attisdropped)
{
*isnull = true;
return (Datum) 0;
}
/*
* Extract the attribute, along with any preceding attributes.
*/
slot_deform_tuple(slot, attnum);
/*
* The result is acquired from tts_values array.
*/
*isnull = slot->tts_isnull[attnum - 1];
return slot->tts_values[attnum - 1];
}
| void slot_getsomeattrs | ( | TupleTableSlot * | slot, | |
| int | attnum | |||
| ) |
Definition at line 1274 of file heaptuple.c.
References elog, ERROR, HeapTupleHeaderGetNatts, Min, tupleDesc::natts, NULL, slot_deform_tuple(), HeapTupleData::t_data, TupleTableSlot::tts_isnull, TupleTableSlot::tts_nvalid, TupleTableSlot::tts_tuple, TupleTableSlot::tts_tupleDescriptor, and TupleTableSlot::tts_values.
Referenced by ExecProject(), lookup_hash_entry(), and process_ordered_aggregate_multi().
{
HeapTuple tuple;
int attno;
/* Quick out if we have 'em all already */
if (slot->tts_nvalid >= attnum)
return;
/* Check for caller error */
if (attnum <= 0 || attnum > slot->tts_tupleDescriptor->natts)
elog(ERROR, "invalid attribute number %d", attnum);
/*
* otherwise we had better have a physical tuple (tts_nvalid should equal
* natts in all virtual-tuple cases)
*/
tuple = slot->tts_tuple;
if (tuple == NULL) /* internal error */
elog(ERROR, "cannot extract attribute from empty tuple slot");
/*
* load up any slots available from physical tuple
*/
attno = HeapTupleHeaderGetNatts(tuple->t_data);
attno = Min(attno, attnum);
slot_deform_tuple(slot, attno);
/*
* If tuple doesn't have all the atts indicated by tupleDesc, read the
* rest as null
*/
for (; attno < attnum; attno++)
{
slot->tts_values[attno] = (Datum) 0;
slot->tts_isnull[attno] = true;
}
slot->tts_nvalid = attnum;
}
1.7.1