14#ifndef SPGIST_PRIVATE_H
15#define SPGIST_PRIVATE_H
19#include "catalog/pg_am_d.h"
32#define SpGistGetFillFactor(relation) \
33 (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \
34 relation->rd_rel->relam == SPGIST_AM_OID), \
35 (relation)->rd_options ? \
36 ((SpGistOptions *) (relation)->rd_options)->fillfactor : \
37 SPGIST_DEFAULT_FILLFACTOR)
38#define SpGistGetTargetPageFreeSpace(relation) \
39 (BLCKSZ * (100 - SpGistGetFillFactor(relation)) / 100)
44#define spgFirstIncludeColumn 1
47#define SPGIST_METAPAGE_BLKNO (0)
48#define SPGIST_ROOT_BLKNO (1)
49#define SPGIST_NULL_BLKNO (2)
50#define SPGIST_LAST_FIXED_BLKNO SPGIST_NULL_BLKNO
52#define SpGistBlockIsRoot(blkno) \
53 ((blkno) == SPGIST_ROOT_BLKNO || (blkno) == SPGIST_NULL_BLKNO)
54#define SpGistBlockIsFixed(blkno) \
55 ((BlockNumber) (blkno) <= (BlockNumber) SPGIST_LAST_FIXED_BLKNO)
72#define SPGIST_META (1<<0)
73#define SPGIST_DELETED (1<<1)
75#define SPGIST_LEAF (1<<2)
76#define SPGIST_NULLS (1<<3)
78#define SpGistPageGetOpaque(page) ((SpGistPageOpaque) PageGetSpecialPointer(page))
79#define SpGistPageIsMeta(page) (SpGistPageGetOpaque(page)->flags & SPGIST_META)
80#define SpGistPageIsDeleted(page) (SpGistPageGetOpaque(page)->flags & SPGIST_DELETED)
81#define SpGistPageIsLeaf(page) (SpGistPageGetOpaque(page)->flags & SPGIST_LEAF)
82#define SpGistPageStoresNulls(page) (SpGistPageGetOpaque(page)->flags & SPGIST_NULLS)
92#define SPGIST_PAGE_ID 0xFF82
106#define SPGIST_CACHED_PAGES 8
122#define SPGIST_MAGIC_NUMBER (0xBA0BABEE)
124#define SpGistPageGetMeta(p) \
125 ((SpGistMetaPageData *) PageGetContents(p))
183#define SizeOfSpGistSearchItem(n_distances) \
184 (offsetof(SpGistSearchItem, distances) + sizeof(double) * (n_distances))
273#define SPGIST_REDIRECT 1
275#define SPGIST_PLACEHOLDER 3
307#define SGITMAXNNODES 0x1FFF
308#define SGITMAXPREFIXSIZE 0xFFFF
309#define SGITMAXSIZE 0xFFFF
311#define SGITHDRSZ MAXALIGN(sizeof(SpGistInnerTupleData))
312#define _SGITDATA(x) (((char *) (x)) + SGITHDRSZ)
313#define SGITDATAPTR(x) ((x)->prefixSize ? _SGITDATA(x) : NULL)
314#define SGITDATUM(x, s) ((x)->prefixSize ? \
315 ((s)->attPrefixType.attbyval ? \
316 *(Datum *) _SGITDATA(x) : \
317 PointerGetDatum(_SGITDATA(x))) \
319#define SGITNODEPTR(x) ((SpGistNodeTuple) (_SGITDATA(x) + (x)->prefixSize))
322#define SGITITERATE(x, i, nt) \
323 for ((i) = 0, (nt) = SGITNODEPTR(x); \
325 (i)++, (nt) = (SpGistNodeTuple) (((char *) (nt)) + IndexTupleSize(nt)))
340#define SGNTHDRSZ MAXALIGN(sizeof(SpGistNodeTupleData))
341#define SGNTDATAPTR(x) (((char *) (x)) + SGNTHDRSZ)
342#define SGNTDATUM(x, s) ((s)->attLabelType.attbyval ? \
343 *(Datum *) SGNTDATAPTR(x) : \
344 PointerGetDatum(SGNTDATAPTR(x)))
395#define SGLT_GET_NEXTOFFSET(spgLeafTuple) \
396 ((spgLeafTuple)->t_info & 0x3FFF)
397#define SGLT_GET_HASNULLMASK(spgLeafTuple) \
398 (((spgLeafTuple)->t_info & 0x8000) ? true : false)
399#define SGLT_SET_NEXTOFFSET(spgLeafTuple, offsetNumber) \
400 ((spgLeafTuple)->t_info = \
401 ((spgLeafTuple)->t_info & 0xC000) | ((offsetNumber) & 0x3FFF))
402#define SGLT_SET_HASNULLMASK(spgLeafTuple, hasnulls) \
403 ((spgLeafTuple)->t_info = \
404 ((spgLeafTuple)->t_info & 0x7FFF) | ((hasnulls) ? 0x8000 : 0))
406#define SGLTHDRSZ(hasnulls) \
407 ((hasnulls) ? MAXALIGN(sizeof(SpGistLeafTupleData) + \
408 sizeof(IndexAttributeBitMapData)) : \
409 MAXALIGN(sizeof(SpGistLeafTupleData)))
410#define SGLTDATAPTR(x) (((char *) (x)) + SGLTHDRSZ(SGLT_GET_HASNULLMASK(x)))
411#define SGLTDATUM(x, s) fetch_att(SGLTDATAPTR(x), \
412 (s)->attLeafType.attbyval, \
413 (s)->attLeafType.attlen)
438#define SGDTSIZE MAXALIGN(sizeof(SpGistDeadTupleData))
448#define SPGIST_PAGE_CAPACITY \
449 MAXALIGN_DOWN(BLCKSZ - \
450 SizeOfPageHeaderData - \
451 MAXALIGN(sizeof(SpGistPageOpaqueData)))
457#define SpGistPageGetFreeSpace(p, n) \
458 (PageGetExactFreeSpace(p) + \
459 Min(SpGistPageGetOpaque(p)->nPlaceholder, n) * \
460 (SGDTSIZE + sizeof(ItemIdData)))
466#define STORE_STATE(s, d) \
468 (d).redirectXid = (s)->redirectXid; \
469 (d).isBuild = (s)->isBuild; \
483#define GBUF_LEAF 0x03
484#define GBUF_INNER_PARITY(x) ((x) % 3)
485#define GBUF_NULLS 0x04
487#define GBUF_PARITY_MASK 0x03
488#define GBUF_REQ_LEAF(flags) (((flags) & GBUF_PARITY_MASK) == GBUF_LEAF)
489#define GBUF_REQ_NULLS(flags) ((flags) & GBUF_NULLS)
494#define SPGIST_MIN_FILLFACTOR 10
495#define SPGIST_DEFAULT_FILLFACTOR 80
503 int needSpace,
bool *isNew);
510 const Datum *datums,
const bool *isnulls);
513 const Datum *datums,
const bool *isnulls);
517 bool hasPrefix,
Datum prefix,
522 Datum *datums,
bool *isnulls,
523 bool keyColumnIsNull);
532 bool *
res,
bool *isnull);
539 int firststate,
int reststate,
546 ScanKey orderbys,
int norderbys);
#define FLEXIBLE_ARRAY_MEMBER
static void PGresult * res
#define MaxIndexTuplesPerPage
static pg_noinline void Size size
BOX * box_copy(BOX *orig)
SpGistDeadTupleData * SpGistDeadTuple
Datum * spgExtractNodeLabels(SpGistState *state, SpGistInnerTuple innerTuple)
void initSpGistState(SpGistState *state, Relation index)
struct SpGistPageOpaqueData SpGistPageOpaqueData
void SpGistUpdateMetaPage(Relation index)
SpGistPageOpaqueData * SpGistPageOpaque
TupleDesc getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType)
Buffer SpGistNewBuffer(Relation index)
SpGistInnerTupleData * SpGistInnerTuple
struct SpGistDeadTupleData SpGistDeadTupleData
SpGistInnerTuple spgFormInnerTuple(SpGistState *state, bool hasPrefix, Datum prefix, int nNodes, SpGistNodeTuple *nodes)
SpGistLeafTuple spgFormLeafTuple(SpGistState *state, ItemPointer heapPtr, const Datum *datums, const bool *isnulls)
bool spgdoinsert(Relation index, SpGistState *state, ItemPointer heapPtr, Datum *datums, bool *isnulls)
SpGistCache * spgGetCache(Relation index)
void spgPageIndexMultiDelete(SpGistState *state, Page page, OffsetNumber *itemnos, int nitems, int firststate, int reststate, BlockNumber blkno, OffsetNumber offnum)
struct SpGistState SpGistState
void spgDeformLeafTuple(SpGistLeafTuple tup, TupleDesc tupleDescriptor, Datum *datums, bool *isnulls, bool keyColumnIsNull)
SpGistDeadTuple spgFormDeadTuple(SpGistState *state, int tupstate, BlockNumber blkno, OffsetNumber offnum)
IndexTupleData SpGistNodeTupleData
SpGistScanOpaqueData * SpGistScanOpaque
struct SpGistInnerTupleData SpGistInnerTupleData
unsigned int SpGistGetInnerTypeSize(SpGistTypeDesc *att, Datum datum)
struct SpGistOptions SpGistOptions
struct SpGistCache SpGistCache
void SpGistInitBuffer(Buffer b, uint16 f)
void spgUpdateNodeLink(SpGistInnerTuple tup, int nodeN, BlockNumber blkno, OffsetNumber offset)
double * spg_key_orderbys_distances(Datum key, bool isLeaf, ScanKey orderbys, int norderbys)
SpGistNodeTupleData * SpGistNodeTuple
struct SpGistMetaPageData SpGistMetaPageData
struct SpGistLastUsedPage SpGistLastUsedPage
Buffer SpGistGetBuffer(Relation index, int flags, int needSpace, bool *isNew)
struct SpGistLeafTupleData * SpGistLeafTuple
#define SPGIST_CACHED_PAGES
bool spgproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull)
void SpGistSetLastUsedPage(Relation index, Buffer buffer)
struct SpGistScanOpaqueData SpGistScanOpaqueData
OffsetNumber SpGistPageAddNewItem(SpGistState *state, Page page, Item item, Size size, OffsetNumber *startOffset, bool errorOK)
struct SpGistTypeDesc SpGistTypeDesc
struct SpGistSearchItem SpGistSearchItem
Size SpGistGetLeafTupleSize(TupleDesc tupleDescriptor, const Datum *datums, const bool *isnulls)
void SpGistInitPage(Page page, uint16 f)
struct SpGistLeafTupleData SpGistLeafTupleData
SpGistNodeTuple spgFormNodeTuple(SpGistState *state, Datum label, bool isnull)
void SpGistInitMetapage(Page page)
struct SpGistLUPCache SpGistLUPCache
SpGistTypeDesc attPrefixType
SpGistTypeDesc attLeafType
SpGistLUPCache lastUsedPages
SpGistTypeDesc attLabelType
SpGistLastUsedPage cachedPage[SPGIST_CACHED_PAGES]
SpGistLUPCache lastUsedPages
HeapTuple reconTups[MaxIndexTuplesPerPage]
ItemPointerData heapPtrs[MaxIndexTuplesPerPage]
MemoryContext traversalCxt
int * nonNullOrderByOffsets
int numberOfNonNullOrderBys
bool recheckDistances[MaxIndexTuplesPerPage]
FmgrInfo leafConsistentFn
IndexOrderByDistance * distances[MaxIndexTuplesPerPage]
bool recheck[MaxIndexTuplesPerPage]
FmgrInfo innerConsistentFn
SpGistLeafTuple leafTuple
double distances[FLEXIBLE_ARRAY_MEMBER]
SpGistTypeDesc attPrefixType
TransactionId redirectXid
SpGistTypeDesc attLabelType
SpGistTypeDesc attLeafType