Example #1
0
/* --------------------------------
 *		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);
	}
}
Example #2
0
/* --------------------------------
 *		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);
}
Example #3
0
/* --------------------------------
 *		ExecDropSingleTupleTableSlot
 *
 *		Release a TupleTableSlot made with MakeSingleTupleTableSlot.
 * --------------------------------
 */
void
ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
{
	/*
	 * sanity checks
	 */
	Assert(slot != NULL);
	cleanup_slot(slot);
	pfree(slot);
}
Example #4
0
/* --------------------------------
 *		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);
	}