#ifndef BRIN_TUPLE_H
#define BRIN_TUPLE_H
#include "access/brin_internal.h"
#include "access/tupdesc.h"
typedef void (*brin_serialize_callback_type) (BrinDesc *bdesc, Datum src, Datum *dst);
typedef struct BrinValues
{
AttrNumber bv_attno;
bool bv_hasnulls;
bool bv_allnulls;
Datum *bv_values;
Datum bv_mem_value;
MemoryContext bv_context;
brin_serialize_callback_type bv_serialize;
} BrinValues;
typedef struct BrinMemTuple
{
bool bt_placeholder;
bool bt_empty_range;
BlockNumber bt_blkno;
MemoryContext bt_context;
Datum *bt_values;
bool *bt_allnulls;
bool *bt_hasnulls;
BrinValues bt_columns[FLEXIBLE_ARRAY_MEMBER];
} BrinMemTuple;
typedef struct BrinTuple
{
BlockNumber bt_blkno;
uint8 bt_info;
} BrinTuple;
#define SizeOfBrinTuple (offsetof(BrinTuple, bt_info) + sizeof(uint8))
#define BRIN_OFFSET_MASK 0x1F
#define BRIN_EMPTY_RANGE_MASK 0x20
#define BRIN_PLACEHOLDER_MASK 0x40
#define BRIN_NULLS_MASK 0x80
#define BrinTupleDataOffset(tup) ((Size) (((BrinTuple *) (tup))->bt_info & BRIN_OFFSET_MASK))
#define BrinTupleHasNulls(tup) (((((BrinTuple *) (tup))->bt_info & BRIN_NULLS_MASK)) != 0)
#define BrinTupleIsPlaceholder(tup) (((((BrinTuple *) (tup))->bt_info & BRIN_PLACEHOLDER_MASK)) != 0)
#define BrinTupleIsEmptyRange(tup) (((((BrinTuple *) (tup))->bt_info & BRIN_EMPTY_RANGE_MASK)) != 0)
extern BrinTuple *brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno,
BrinMemTuple *tuple, Size *size);
extern BrinTuple *brin_form_placeholder_tuple(BrinDesc *brdesc,
BlockNumber blkno, Size *size);
extern void brin_free_tuple(BrinTuple *tuple);
extern BrinTuple *brin_copy_tuple(BrinTuple *tuple, Size len,
BrinTuple *dest, Size *destsz);
extern bool brin_tuples_equal(const BrinTuple *a, Size alen,
const BrinTuple *b, Size blen);
extern BrinMemTuple *brin_new_memtuple(BrinDesc *brdesc);
extern BrinMemTuple *brin_memtuple_initialize(BrinMemTuple *dtuple,
BrinDesc *brdesc);
extern BrinMemTuple *brin_deform_tuple(BrinDesc *brdesc,
BrinTuple *tuple, BrinMemTuple *dMemtuple);
#endif