#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
static inline Size
IndexTupleSize(const IndexTupleData *itup)
{
return (itup->t_info & INDEX_SIZE_MASK);
}
static inline bool
IndexTupleHasNulls(const IndexTupleData *itup)
{
return itup->t_info & INDEX_NULL_MASK;
}
static inline bool
IndexTupleHasVarwidths(const IndexTupleData *itup)
{
return 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))
{
CompactAttribute *attr = TupleDescCompactAttr(tupleDesc, attnum - 1);
if (attr->attcacheoff >= 0)
{
return fetchatt(attr,
(char *) tup + IndexInfoFindDataOffset(tup->t_info) +
attr->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