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)
43 #define spgKeyColumn 0
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))
272 #define SPGIST_LIVE 0
273 #define SPGIST_REDIRECT 1
274 #define SPGIST_DEAD 2
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
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)
BOX * box_copy(BOX *orig)
SpGistLeafTuple spgFormLeafTuple(SpGistState *state, ItemPointer heapPtr, const Datum *datums, const bool *isnulls)
bool spgdoinsert(Relation index, SpGistState *state, ItemPointer heapPtr, Datum *datums, bool *isnulls)
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)
double * spg_key_orderbys_distances(Datum key, bool isLeaf, ScanKey orderbys, int norderbys)
void spgUpdateNodeLink(SpGistInnerTuple tup, int nodeN, BlockNumber blkno, OffsetNumber offset)
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
SpGistCache * spgGetCache(Relation index)
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