/* -------------------------------- * ExecSetSlotDescriptor * * This function is used to set the tuple descriptor associated * with the slot's tuple. The passed descriptor must have lifespan * at least equal to the slot's. If it is a reference-counted descriptor * then the reference count is incremented for as long as the slot holds * a reference. * -------------------------------- */ void ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */ TupleDesc tupdesc) /* new tuple descriptor */ { /* For safety, make sure slot is empty before changing it */ cleanup_slot(slot); /* * 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. */ MemoryContext oldcontext = MemoryContextSwitchTo(slot->tts_mcxt); slot->tts_mt_bind = create_memtuple_binding(tupdesc); slot->PRIVATE_tts_values = (Datum *) palloc(tupdesc->natts * sizeof(Datum)); slot->PRIVATE_tts_isnull = (bool *) palloc(tupdesc->natts * sizeof(bool)); MemoryContextSwitchTo(oldcontext); } }
/* -------------------------------- * ExecDropTupleTable * * This frees the storage used by the tuple table itself * and optionally frees the contents of the table also. * It is expected that this routine be called by EndPlan(). * -------------------------------- */ void ExecDropTupleTable(TupleTable table, /* tuple table */ bool shouldFree) /* true if we should free slot * contents */ { /* * sanity checks */ Assert(table != NULL); /* * first free all the valid pointers in the tuple array and drop refcounts * of any referenced buffers, if that's what the caller wants. (There is * probably no good reason for the caller ever not to want it!) */ if (shouldFree) { int next = table->next; int i; for (i = 0; i < next; i++) { cleanup_slot(&(table->array[i])); } } /* * finally free the tuple table itself. */ pfree(table); }
/* -------------------------------- * ExecDropSingleTupleTableSlot * * Release a TupleTableSlot made with MakeSingleTupleTableSlot. * -------------------------------- */ void ExecDropSingleTupleTableSlot(TupleTableSlot *slot) { /* * sanity checks */ Assert(slot != NULL); cleanup_slot(slot); pfree(slot); }
/* -------------------------------- * ExecResetTupleTable * * This releases any resources (buffer pins, tupdesc refcounts) * held by the tuple table, and optionally releases the memory * occupied by the tuple table data structure. * It is expected that this routine be called by EndPlan(). * -------------------------------- */ void ExecResetTupleTable(List *tupleTable, /* tuple table */ bool shouldFree) /* true if we should free memory */ { 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) cleanup_slot(slot); /* If shouldFree, release memory occupied by the slot itself */ if (shouldFree) pfree(slot); }