/*-------------------------------------------------------------------------
 *
 * tuptable.h
 *	  tuple table support stuff
 *
 *
 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * $PostgreSQL: pgsql/src/include/executor/tuptable.h,v 1.36 2006/10/04 00:30:08 momjian Exp $
 *
 *-------------------------------------------------------------------------
 */
#ifndef TUPTABLE_H
#define TUPTABLE_H

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

/*----------
 * The executor stores tuples in a "tuple table" which is composed of
 * independent TupleTableSlots.  There are several cases we need to handle:
 *		1. physical tuple in a disk buffer page
 *		2. physical tuple constructed in palloc'ed memory
 *		3. "minimal" physical tuple constructed in palloc'ed memory
 *		4. "virtual" tuple consisting of Datum/isnull arrays
 *
 * The first two cases are similar in that they both deal with "materialized"
 * tuples, but resource management is different.  For a tuple in a disk page
 * we need to hold a pin on the buffer until the TupleTableSlot's reference
 * to the tuple is dropped; while for a palloc'd tuple we usually want the
 * tuple pfree'd when the TupleTableSlot's reference is dropped.
 *
 * A "minimal" tuple is handled similarly to a palloc'd regular tuple.
 * At present, minimal tuples never are stored in buffers, so there is no
 * parallel to case 1.	Note that a minimal tuple has no "system columns".
 * (Actually, it could have an OID, but we have no need to access the OID.)
 *
 * A "virtual" tuple is an optimization used to minimize physical data
 * copying in a nest of plan nodes.  Any pass-by-reference Datums in the
 * tuple point to storage that is not directly associated with the
 * TupleTableSlot; generally they will point to part of a tuple stored in
 * a lower plan node's output TupleTableSlot, or to a function result
 * constructed in a plan node's per-tuple econtext.  It is the responsibility
 * of the generating plan node to be sure these resources are not released
 * for as long as the virtual tuple needs to be valid.	We only use virtual
 * tuples in the result slots of plan nodes --- tuples to be copied anywhere
 * else need to be "materialized" into physical tuples.  Note also that a
 * virtual tuple does not have any "system columns".
 *
 * The Datum/isnull arrays of a TupleTableSlot serve double duty.  When the
 * slot contains a virtual tuple, they are the authoritative data.	When the
 * slot contains a physical tuple, the arrays contain data extracted from
 * the tuple.  (In this state, any pass-by-reference Datums point into
 * the physical tuple.)  The extracted information is built "lazily",
 * ie, only as needed.	This serves to avoid repeated extraction of data
 * from the physical tuple.
 *
 * A TupleTableSlot can also be "empty", holding no valid data.  This is
 * the only valid state for a freshly-created slot that has not yet had a
 * tuple descriptor assigned to it.  In this state, tts_isempty must be
 * TRUE, tts_shouldFree FALSE, tts_tuple NULL, tts_buffer InvalidBuffer,
 * and tts_nvalid zero.
 *
 * The tupleDescriptor is simply referenced, not copied, by the TupleTableSlot
 * code.  The caller of ExecSetSlotDescriptor() is responsible for providing
 * a descriptor that will live as long as the slot does.  (Typically, both
 * slots and descriptors are in per-query memory and are freed by memory
 * context deallocation at query end; so it's not worth providing any extra
 * mechanism to do more.  However, the slot will increment the tupdesc
 * reference count if a reference-counted tupdesc is supplied.)
 *
 * When tts_shouldFree is true, the physical tuple is "owned" by the slot
 * and should be freed when the slot's reference to the tuple is dropped.
 *
 * If tts_buffer is not InvalidBuffer, then the slot is holding a pin
 * on the indicated buffer page; drop the pin when we release the
 * slot's reference to that buffer.  (tts_shouldFree should always be
 * false in such a case, since presumably tts_tuple is pointing at the
 * buffer page.)
 *
 * tts_nvalid indicates the number of valid columns in the tts_values/isnull
 * arrays.	When the slot is holding a "virtual" tuple this must be equal
 * to the descriptor's natts.  When the slot is holding a physical tuple
 * this is equal to the number of columns we have extracted (we always
 * extract columns from left to right, so there are no holes).
 *
 * tts_values/tts_isnull are allocated when a descriptor is assigned to the
 * slot; they are of length equal to the descriptor's natts.
 *
 * tts_mintuple must always be NULL if the slot does not hold a "minimal"
 * tuple.  When it does, tts_mintuple points to the actual MinimalTupleData
 * object (the thing to be pfree'd if tts_shouldFree is true).  In this case
 * tts_tuple points at tts_minhdr and the fields of that are set correctly
 * for access to the minimal tuple; in particular, tts_minhdr.t_data points
 * MINIMAL_TUPLE_OFFSET bytes before tts_mintuple.	(tts_mintuple is therefore
 * redundant, but for code simplicity we store it explicitly anyway.)  This
 * case otherwise behaves identically to the regular-physical-tuple case.
 *
 * tts_slow/tts_off are saved state for slot_deform_tuple, and should not
 * be touched by any other code.
 *----------
 */

/* tts_flags */
#define         TTS_ISEMPTY     1
#define         TTS_SHOULDFREE 	2
#define         TTS_VIRTUAL     4

typedef struct TupleTableSlot
{
	NodeTag		type;		/* vestigial ... allows IsA tests */
	int         PRIVATE_tts_flags;      /* TTS_xxx flags */

	/* Heap tuple stuff */
	HeapTuple PRIVATE_tts_heaptuple;
	void    *PRIVATE_tts_htup_buf;
	uint32   PRIVATE_tts_htup_buf_len;

	/* Mem tuple stuff */
	MemTuple PRIVATE_tts_memtuple;
	void 	*PRIVATE_tts_mtup_buf;
	uint32  PRIVATE_tts_mtup_buf_len;
	ItemPointerData PRIVATE_tts_synthetic_ctid;	/* needed if memtuple is stored on disk */
	
	/* Virtual tuple stuff */
	int 	PRIVATE_tts_nvalid;		/* number of valid virtual tup entries */
	long    PRIVATE_tts_off; 		/* hack to remember state of last decoding. */
	bool    PRIVATE_tts_slow; 		/* hack to remember state of last decoding. */
	Datum 	*PRIVATE_tts_values;		/* virtual tuple values */
	bool 	*PRIVATE_tts_isnull;		/* virtual tuple nulls */

	TupleDesc	tts_tupleDescriptor;	/* slot's tuple descriptor */
	MemTupleBinding *tts_mt_bind;		/* mem tuple's binding */ 
	MemoryContext 	tts_mcxt;		/* slot itself is in this context */
	Buffer		tts_buffer;		/* tuple's buffer, or InvalidBuffer */

    /* System attributes */
    Oid         tts_tableOid;
    uint32      tts_rangeid;
} TupleTableSlot;

static inline bool TupIsNull(TupleTableSlot *slot)
{
	return (slot == NULL || (slot->PRIVATE_tts_flags & TTS_ISEMPTY) != 0);
}
static inline void TupClearIsEmpty(TupleTableSlot *slot)
{
	slot->PRIVATE_tts_flags &= (~TTS_ISEMPTY);
}
static inline bool TupShouldFree(TupleTableSlot *slot)
{
	Assert(slot);
	return ((slot->PRIVATE_tts_flags & TTS_SHOULDFREE) != 0); 
}
static inline void TupSetShouldFree(TupleTableSlot *slot)
{
	slot->PRIVATE_tts_flags |= TTS_SHOULDFREE; 
}
static inline void TupClearShouldFree(TupleTableSlot *slot)
{
	slot->PRIVATE_tts_flags &= (~TTS_SHOULDFREE);
}
static inline bool TupHasHeapTuple(TupleTableSlot *slot)
{
	Assert(slot);
	return slot->PRIVATE_tts_heaptuple != NULL;
}
static inline bool TupHasMemTuple(TupleTableSlot *slot)
{
	Assert(slot);
	return slot->PRIVATE_tts_memtuple != NULL;
}
static inline bool TupHasVirtualTuple(TupleTableSlot *slot)
{
	Assert(slot);
    return (slot->PRIVATE_tts_flags & TTS_VIRTUAL) ? true : false;
}
static inline HeapTuple TupGetHeapTuple(TupleTableSlot *slot)
{
	Assert(TupHasHeapTuple(slot));
	Assert(!is_heaptuple_memtuple(slot->PRIVATE_tts_heaptuple));
	return slot->PRIVATE_tts_heaptuple; 
}
static inline MemTuple TupGetMemTuple(TupleTableSlot *slot)
{
	Assert(TupHasMemTuple(slot));
	return slot->PRIVATE_tts_memtuple;
}

static inline void free_heaptuple_memtuple(TupleTableSlot *slot)
{
	if(TupShouldFree(slot))
	{
		if(slot->PRIVATE_tts_heaptuple && slot->PRIVATE_tts_heaptuple != slot->PRIVATE_tts_htup_buf)
			pfree(slot->PRIVATE_tts_heaptuple);
		
		if(slot->PRIVATE_tts_memtuple && slot->PRIVATE_tts_memtuple != slot->PRIVATE_tts_mtup_buf)
			pfree(slot->PRIVATE_tts_memtuple);
	}

	slot->PRIVATE_tts_heaptuple = NULL;
	slot->PRIVATE_tts_memtuple = NULL;
}

static inline void TupSetVirtualTuple(TupleTableSlot *slot)
{
	Assert(slot);
	slot->PRIVATE_tts_flags |= TTS_VIRTUAL;
}

static inline void TupSetVirtualTupleNValid(TupleTableSlot *slot, int nvalid)
{
        free_heaptuple_memtuple(slot);
        slot->PRIVATE_tts_flags = TTS_VIRTUAL;
        slot->PRIVATE_tts_nvalid = nvalid;
}

static inline Datum *slot_get_values(TupleTableSlot *slot)
{
	return slot->PRIVATE_tts_values;
}

static inline bool *slot_get_isnull(TupleTableSlot *slot)
{
	return slot->PRIVATE_tts_isnull;
}

extern void _slot_getsomeattrs(TupleTableSlot *slot, int attnum);
static inline void slot_getsomeattrs(TupleTableSlot *slot, int attnum)
{

	if(TupHasVirtualTuple(slot))
	{
		if(slot->PRIVATE_tts_nvalid >= attnum)
			return;
	}

	if(TupHasMemTuple(slot))
	{
		int i; 
		for(i=0; i<attnum; ++i)
			slot->PRIVATE_tts_values[i] = memtuple_getattr(
					slot->PRIVATE_tts_memtuple, slot->tts_mt_bind, 
					i+1, &(slot->PRIVATE_tts_isnull[i]));

		TupSetVirtualTuple(slot);
		slot->PRIVATE_tts_nvalid = attnum;
		return;
	}

	_slot_getsomeattrs(slot, attnum); 
	TupSetVirtualTuple(slot);
}


static inline void slot_getallattrs(TupleTableSlot *slot)
{
	slot_getsomeattrs(slot, slot->tts_tupleDescriptor->natts);
}

extern Datum slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull);

/*
 * Set the synthetic ctid to a given ctid value.
 *
 * If the slot contains a memtuple or a virtual tuple, the PRIVATE_tts_synthetic_ctid
 * is set to the given ctid value. If the slot contains a heap tuple, then t_self
 * in the heap tuple is set to the given ctid value.
 *
 * This function will set both PRIVATE_tts_synthetic_ctid and heaptuple->t_self when
 * both heap tuple and memtuple or virtual tuple are presented.
 */
static inline void slot_set_ctid(TupleTableSlot *slot, ItemPointer new_ctid)
{
	Assert(slot);

	if (TupHasHeapTuple(slot))
	{
		HeapTuple tuple = TupGetHeapTuple(slot);
		tuple->t_self = *new_ctid;
	}
	
	if (TupHasMemTuple(slot) || TupHasVirtualTuple(slot))
		slot->PRIVATE_tts_synthetic_ctid = *new_ctid;
}

extern void slot_set_ctid_from_fake(TupleTableSlot *slot, ItemPointerData *fake_ctid);

/*
 * Retrieve the synthetic ctid value from the slot.
 *
 * This function assumes that the PRIVATE_tts_synthetic_ctid and heaptuple->t_self
 * are in sync if both of them are presented in the slot.
 */
static inline ItemPointer slot_get_ctid(TupleTableSlot *slot)
{
	if (TupHasHeapTuple(slot))
	{
		Assert(ItemPointerIsValid(&(slot->PRIVATE_tts_heaptuple->t_self)));
		return &(slot->PRIVATE_tts_heaptuple->t_self);
	}
	return &(slot->PRIVATE_tts_synthetic_ctid);
}

/*
 * Get an attribute from the tuple table slot.
 */
static inline Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
{
	Assert(!TupIsNull(slot));
	Assert(attnum <= slot->tts_tupleDescriptor->natts);

	/* System attribute */
	if(attnum <= 0)
		return slot_getsysattr(slot, attnum, isnull);

	/* fast path for virtual tuple */
	if(TupHasVirtualTuple(slot) && slot->PRIVATE_tts_nvalid >= attnum)
	{
		*isnull = slot->PRIVATE_tts_isnull[attnum-1];
		return slot->PRIVATE_tts_values[attnum-1];
	}

	/* Mem tuple: We do not even populate virtual tuple */
	if(TupHasMemTuple(slot))
	{
		Assert(slot->tts_mt_bind);
		return memtuple_getattr(slot->PRIVATE_tts_memtuple, slot->tts_mt_bind, attnum, isnull);
	}

	/* Slow: heap tuple */
	Assert(TupHasHeapTuple(slot));

	_slot_getsomeattrs(slot, attnum);
	Assert(TupHasVirtualTuple(slot) && slot->PRIVATE_tts_nvalid >= attnum);
	*isnull = slot->PRIVATE_tts_isnull[attnum-1];
	return slot->PRIVATE_tts_values[attnum-1];
}

static inline bool slot_attisnull(TupleTableSlot *slot, int attnum)
{
	if(attnum <= 0)
		return false;

	if(TupHasHeapTuple(slot))
		return heap_attisnull_normalattr(slot->PRIVATE_tts_heaptuple, attnum);
		
	if(TupHasVirtualTuple(slot) && slot->PRIVATE_tts_nvalid >= attnum)
		return slot->PRIVATE_tts_isnull[attnum-1];

	Assert(TupHasMemTuple(slot));
	return memtuple_attisnull(slot->PRIVATE_tts_memtuple, slot->tts_mt_bind, attnum);
}

/*
 * Tuple table data structure: an array of TupleTableSlots.
 */
typedef struct TupleTableData
{
	int			size;			/* size of the table (number of slots) */
	int			next;			/* next available slot number */
	TupleTableSlot array[1];	/* VARIABLE LENGTH ARRAY - must be last */
} TupleTableData;				/* VARIABLE LENGTH STRUCT */

typedef TupleTableData *TupleTable;

/* in executor/execTuples.c */
extern void init_slot(TupleTableSlot *slot, TupleDesc tupdesc);

extern TupleTable ExecCreateTupleTable(int tableSize);
extern void ExecDropTupleTable(TupleTable table, bool shouldFree);
extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc);
extern void ExecDropSingleTupleTableSlot(TupleTableSlot *slot);
extern TupleTableSlot *ExecAllocTableSlot(TupleTable table);
extern void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc); 

extern TupleTableSlot *ExecStoreHeapTuple(HeapTuple tuple,
			   TupleTableSlot *slot,
			   Buffer buffer,
			   bool shouldFree);
extern TupleTableSlot *ExecStoreMemTuple(MemTuple mtup,
					  TupleTableSlot *slot,
					  bool shouldFree);

extern TupleTableSlot *ExecClearTuple(TupleTableSlot *slot);
extern TupleTableSlot *ExecStoreVirtualTuple(TupleTableSlot *slot);
extern TupleTableSlot *ExecStoreAllNullTuple(TupleTableSlot *slot);

extern HeapTuple ExecCopySlotHeapTuple(TupleTableSlot *slot);
extern HeapTuple ExecCopySlotHeapTupleTo(TupleTableSlot *slot, MemoryContext pctxt, char *dest, unsigned int *len);
extern MemTuple ExecCopySlotMemTuple(TupleTableSlot *slot);
extern MemTuple ExecCopySlotMemTupleTo(TupleTableSlot *slot, MemoryContext pctxt, char *dest, unsigned int *len);

extern HeapTuple ExecFetchSlotHeapTuple(TupleTableSlot *slot);
extern MemTuple ExecFetchSlotMemTuple(TupleTableSlot *slot, bool inline_toast);

extern Datum ExecFetchSlotTupleDatum(TupleTableSlot *slot);

static inline void *ExecFetchSlotGenericTuple(TupleTableSlot *slot, bool mtup_inline_toast)
{
	Assert(!TupIsNull(slot));
	if (slot->PRIVATE_tts_memtuple == NULL && slot->PRIVATE_tts_heaptuple != NULL)
		return (void *) slot->PRIVATE_tts_heaptuple;

	return ExecFetchSlotMemTuple(slot, mtup_inline_toast);
}

static inline TupleTableSlot *ExecStoreGenericTuple(void *tup, TupleTableSlot *slot, bool shouldFree)
{
	if(is_heaptuple_memtuple((HeapTuple) tup))
		return ExecStoreMemTuple((MemTuple) tup, slot, shouldFree);

	return ExecStoreHeapTuple((HeapTuple) tup, slot, InvalidBuffer, shouldFree);
}

static inline HeapTuple ExecCopyGenericTuple(TupleTableSlot *slot)
{
	Assert(!TupIsNull(slot));
	if(slot->PRIVATE_tts_heaptuple != NULL && slot->PRIVATE_tts_memtuple == NULL)
		return ExecCopySlotHeapTuple(slot);
	return (HeapTuple) ExecCopySlotMemTuple(slot);
}

extern TupleTableSlot *ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot);

extern void ExecModifyMemTuple(TupleTableSlot *slot, Datum *values, bool *isnull, bool *doRepl);
#endif   /* TUPTABLE_H */
