#ifndef ITUP_H
#define ITUP_H
#include "access/tupdesc.h"
#include "access/tupmacs.h"
#include "storage/bufpage.h"
#include "storage/itemptr.h"
typedef struct IndexTupleData
{
ItemPointerData t_tid;
unsigned short t_info;
} IndexTupleData;
typedef IndexTupleData *IndexTuple;
typedef struct IndexAttributeBitMapData
{
bits8 bits[(INDEX_MAX_KEYS + 8 - 1) / 8];
} IndexAttributeBitMapData;
typedef IndexAttributeBitMapData * IndexAttributeBitMap;
#define INDEX_SIZE_MASK 0x1FFF
#define INDEX_AM_RESERVED_BIT 0x2000
#define INDEX_VAR_MASK 0x4000
#define INDEX_NULL_MASK 0x8000
#define IndexTupleSize(itup) ((Size) ((itup)->t_info & INDEX_SIZE_MASK))
#define IndexTupleHasNulls(itup) ((((IndexTuple) (itup))->t_info & INDEX_NULL_MASK))
#define IndexTupleHasVarwidths(itup) ((((IndexTuple) (itup))->t_info & INDEX_VAR_MASK))
extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
const Datum *values, const bool *isnull);
extern IndexTuple index_form_tuple_context(TupleDesc tupleDescriptor,
const Datum *values, const bool *isnull,
MemoryContext context);
extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
TupleDesc tupleDesc);
extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,
Datum *values, bool *isnull);
extern void index_deform_tuple_internal(TupleDesc tupleDescriptor,
Datum *values, bool *isnull,
char *tp, bits8 *bp, int hasnulls);
extern IndexTuple CopyIndexTuple(IndexTuple source);
extern IndexTuple index_truncate_tuple(TupleDesc sourceDescriptor,
IndexTuple source, int leavenatts);
static inline Size
IndexInfoFindDataOffset(unsigned short t_info)
{
if (!(t_info & INDEX_NULL_MASK))
return MAXALIGN(sizeof(IndexTupleData));
else
return MAXALIGN(sizeof(IndexTupleData) + sizeof(IndexAttributeBitMapData));
}
#ifndef FRONTEND
static inline Datum
index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
{
Assert(PointerIsValid(isnull));
Assert(attnum > 0);
*isnull = false;
if (!IndexTupleHasNulls(tup))
{
if (TupleDescAttr(tupleDesc, attnum - 1)->attcacheoff >= 0)
{
return fetchatt(TupleDescAttr(tupleDesc, attnum - 1),
(char *) tup + IndexInfoFindDataOffset(tup->t_info)
+ TupleDescAttr(tupleDesc, attnum - 1)->attcacheoff);
}
else
return nocache_index_getattr(tup, attnum, tupleDesc);
}
else
{
if (att_isnull(attnum - 1, (bits8 *) tup + sizeof(IndexTupleData)))
{
*isnull = true;
return (Datum) NULL;
}
else
return nocache_index_getattr(tup, attnum, tupleDesc);
}
}
#endif
#define MaxIndexTuplesPerPage \
((int) ((BLCKSZ - SizeOfPageHeaderData) / \
(MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
#endif