#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; }