spgist_private.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. /*-------------------------------------------------------------------------
  2. *
  3. * spgist_private.h
  4. * Private declarations for SP-GiST access method.
  5. *
  6. *
  7. * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  8. * Portions Copyright (c) 1994, Regents of the University of California
  9. *
  10. * src/include/access/spgist_private.h
  11. *
  12. *-------------------------------------------------------------------------
  13. */
  14. #ifndef SPGIST_PRIVATE_H
  15. #define SPGIST_PRIVATE_H
  16. #include "access/itup.h"
  17. #include "access/spgist.h"
  18. #include "catalog/pg_am_d.h"
  19. #include "nodes/tidbitmap.h"
  20. #include "storage/buf.h"
  21. #include "utils/geo_decls.h"
  22. #include "utils/relcache.h"
  23. typedef struct SpGistOptions
  24. {
  25. int32 varlena_header_; /* varlena header (do not touch directly!) */
  26. int fillfactor; /* page fill factor in percent (0..100) */
  27. } SpGistOptions;
  28. #define SpGistGetFillFactor(relation) \
  29. (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \
  30. relation->rd_rel->relam == SPGIST_AM_OID), \
  31. (relation)->rd_options ? \
  32. ((SpGistOptions *) (relation)->rd_options)->fillfactor : \
  33. SPGIST_DEFAULT_FILLFACTOR)
  34. #define SpGistGetTargetPageFreeSpace(relation) \
  35. (BLCKSZ * (100 - SpGistGetFillFactor(relation)) / 100)
  36. /* SPGiST leaf tuples have one key column, optionally have included columns */
  37. #define spgKeyColumn 0
  38. #define spgFirstIncludeColumn 1
  39. /* Page numbers of fixed-location pages */
  40. #define SPGIST_METAPAGE_BLKNO (0) /* metapage */
  41. #define SPGIST_ROOT_BLKNO (1) /* root for normal entries */
  42. #define SPGIST_NULL_BLKNO (2) /* root for null-value entries */
  43. #define SPGIST_LAST_FIXED_BLKNO SPGIST_NULL_BLKNO
  44. #define SpGistBlockIsRoot(blkno) \
  45. ((blkno) == SPGIST_ROOT_BLKNO || (blkno) == SPGIST_NULL_BLKNO)
  46. #define SpGistBlockIsFixed(blkno) \
  47. ((BlockNumber) (blkno) <= (BlockNumber) SPGIST_LAST_FIXED_BLKNO)
  48. /*
  49. * Contents of page special space on SPGiST index pages
  50. */
  51. typedef struct SpGistPageOpaqueData
  52. {
  53. uint16 flags; /* see bit definitions below */
  54. uint16 nRedirection; /* number of redirection tuples on page */
  55. uint16 nPlaceholder; /* number of placeholder tuples on page */
  56. /* note there's no count of either LIVE or DEAD tuples ... */
  57. uint16 spgist_page_id; /* for identification of SP-GiST indexes */
  58. } SpGistPageOpaqueData;
  59. typedef SpGistPageOpaqueData *SpGistPageOpaque;
  60. /* Flag bits in page special space */
  61. #define SPGIST_META (1<<0)
  62. #define SPGIST_DELETED (1<<1) /* never set, but keep for backwards
  63. * compatibility */
  64. #define SPGIST_LEAF (1<<2)
  65. #define SPGIST_NULLS (1<<3)
  66. #define SpGistPageGetOpaque(page) ((SpGistPageOpaque) PageGetSpecialPointer(page))
  67. #define SpGistPageIsMeta(page) (SpGistPageGetOpaque(page)->flags & SPGIST_META)
  68. #define SpGistPageIsDeleted(page) (SpGistPageGetOpaque(page)->flags & SPGIST_DELETED)
  69. #define SpGistPageIsLeaf(page) (SpGistPageGetOpaque(page)->flags & SPGIST_LEAF)
  70. #define SpGistPageStoresNulls(page) (SpGistPageGetOpaque(page)->flags & SPGIST_NULLS)
  71. /*
  72. * The page ID is for the convenience of pg_filedump and similar utilities,
  73. * which otherwise would have a hard time telling pages of different index
  74. * types apart. It should be the last 2 bytes on the page. This is more or
  75. * less "free" due to alignment considerations.
  76. *
  77. * See comments above GinPageOpaqueData.
  78. */
  79. #define SPGIST_PAGE_ID 0xFF82
  80. /*
  81. * Each backend keeps a cache of last-used page info in its index->rd_amcache
  82. * area. This is initialized from, and occasionally written back to,
  83. * shared storage in the index metapage.
  84. */
  85. typedef struct SpGistLastUsedPage
  86. {
  87. BlockNumber blkno; /* block number, or InvalidBlockNumber */
  88. int freeSpace; /* page's free space (could be obsolete!) */
  89. } SpGistLastUsedPage;
  90. /* Note: indexes in cachedPage[] match flag assignments for SpGistGetBuffer */
  91. #define SPGIST_CACHED_PAGES 8
  92. typedef struct SpGistLUPCache
  93. {
  94. SpGistLastUsedPage cachedPage[SPGIST_CACHED_PAGES];
  95. } SpGistLUPCache;
  96. /*
  97. * metapage
  98. */
  99. typedef struct SpGistMetaPageData
  100. {
  101. uint32 magicNumber; /* for identity cross-check */
  102. SpGistLUPCache lastUsedPages; /* shared storage of last-used info */
  103. } SpGistMetaPageData;
  104. #define SPGIST_MAGIC_NUMBER (0xBA0BABEE)
  105. #define SpGistPageGetMeta(p) \
  106. ((SpGistMetaPageData *) PageGetContents(p))
  107. /*
  108. * Private state of index AM. SpGistState is common to both insert and
  109. * search code; SpGistScanOpaque is for searches only.
  110. */
  111. typedef struct SpGistLeafTupleData *SpGistLeafTuple; /* forward reference */
  112. /* Per-datatype info needed in SpGistState */
  113. typedef struct SpGistTypeDesc
  114. {
  115. Oid type;
  116. int16 attlen;
  117. bool attbyval;
  118. char attalign;
  119. char attstorage;
  120. } SpGistTypeDesc;
  121. typedef struct SpGistState
  122. {
  123. Relation index; /* index we're working with */
  124. spgConfigOut config; /* filled in by opclass config method */
  125. SpGistTypeDesc attType; /* type of values to be indexed/restored */
  126. SpGistTypeDesc attLeafType; /* type of leaf-tuple values */
  127. SpGistTypeDesc attPrefixType; /* type of inner-tuple prefix values */
  128. SpGistTypeDesc attLabelType; /* type of node label values */
  129. /* leafTupDesc typically points to index's tupdesc, but not always */
  130. TupleDesc leafTupDesc; /* descriptor for leaf-level tuples */
  131. char *deadTupleStorage; /* workspace for spgFormDeadTuple */
  132. TransactionId myXid; /* XID to use when creating a redirect tuple */
  133. bool isBuild; /* true if doing index build */
  134. } SpGistState;
  135. /* Item to be re-examined later during a search */
  136. typedef struct SpGistSearchItem
  137. {
  138. pairingheap_node phNode; /* pairing heap node */
  139. Datum value; /* value reconstructed from parent, or
  140. * leafValue if isLeaf */
  141. SpGistLeafTuple leafTuple; /* whole leaf tuple, if needed */
  142. void *traversalValue; /* opclass-specific traverse value */
  143. int level; /* level of items on this page */
  144. ItemPointerData heapPtr; /* heap info, if heap tuple */
  145. bool isNull; /* SearchItem is NULL item */
  146. bool isLeaf; /* SearchItem is heap item */
  147. bool recheck; /* qual recheck is needed */
  148. bool recheckDistances; /* distance recheck is needed */
  149. /* array with numberOfOrderBys entries */
  150. double distances[FLEXIBLE_ARRAY_MEMBER];
  151. } SpGistSearchItem;
  152. #define SizeOfSpGistSearchItem(n_distances) \
  153. (offsetof(SpGistSearchItem, distances) + sizeof(double) * (n_distances))
  154. /*
  155. * Private state of an index scan
  156. */
  157. typedef struct SpGistScanOpaqueData
  158. {
  159. SpGistState state; /* see above */
  160. pairingheap *scanQueue; /* queue of to be visited items */
  161. MemoryContext tempCxt; /* short-lived memory context */
  162. MemoryContext traversalCxt; /* single scan lifetime memory context */
  163. /* Control flags showing whether to search nulls and/or non-nulls */
  164. bool searchNulls; /* scan matches (all) null entries */
  165. bool searchNonNulls; /* scan matches (some) non-null entries */
  166. /* Index quals to be passed to opclass (null-related quals removed) */
  167. int numberOfKeys; /* number of index qualifier conditions */
  168. ScanKey keyData; /* array of index qualifier descriptors */
  169. int numberOfOrderBys; /* number of ordering operators */
  170. int numberOfNonNullOrderBys; /* number of ordering operators
  171. * with non-NULL arguments */
  172. ScanKey orderByData; /* array of ordering op descriptors */
  173. Oid *orderByTypes; /* array of ordering op return types */
  174. int *nonNullOrderByOffsets; /* array of offset of non-NULL
  175. * ordering keys in the original array */
  176. Oid indexCollation; /* collation of index column */
  177. /* Opclass defined functions: */
  178. FmgrInfo innerConsistentFn;
  179. FmgrInfo leafConsistentFn;
  180. /* Pre-allocated workspace arrays: */
  181. double *zeroDistances;
  182. double *infDistances;
  183. /* These fields are only used in amgetbitmap scans: */
  184. TIDBitmap *tbm; /* bitmap being filled */
  185. int64 ntids; /* number of TIDs passed to bitmap */
  186. /* These fields are only used in amgettuple scans: */
  187. bool want_itup; /* are we reconstructing tuples? */
  188. TupleDesc reconTupDesc; /* if so, descriptor for reconstructed tuples */
  189. int nPtrs; /* number of TIDs found on current page */
  190. int iPtr; /* index for scanning through same */
  191. ItemPointerData heapPtrs[MaxIndexTuplesPerPage]; /* TIDs from cur page */
  192. bool recheck[MaxIndexTuplesPerPage]; /* their recheck flags */
  193. bool recheckDistances[MaxIndexTuplesPerPage]; /* distance recheck
  194. * flags */
  195. HeapTuple reconTups[MaxIndexTuplesPerPage]; /* reconstructed tuples */
  196. /* distances (for recheck) */
  197. IndexOrderByDistance *distances[MaxIndexTuplesPerPage];
  198. /*
  199. * Note: using MaxIndexTuplesPerPage above is a bit hokey since
  200. * SpGistLeafTuples aren't exactly IndexTuples; however, they are larger,
  201. * so this is safe.
  202. */
  203. } SpGistScanOpaqueData;
  204. typedef SpGistScanOpaqueData *SpGistScanOpaque;
  205. /*
  206. * This struct is what we actually keep in index->rd_amcache. It includes
  207. * static configuration information as well as the lastUsedPages cache.
  208. */
  209. typedef struct SpGistCache
  210. {
  211. spgConfigOut config; /* filled in by opclass config method */
  212. SpGistTypeDesc attType; /* type of values to be indexed/restored */
  213. SpGistTypeDesc attLeafType; /* type of leaf-tuple values */
  214. SpGistTypeDesc attPrefixType; /* type of inner-tuple prefix values */
  215. SpGistTypeDesc attLabelType; /* type of node label values */
  216. SpGistLUPCache lastUsedPages; /* local storage of last-used info */
  217. } SpGistCache;
  218. /*
  219. * SPGiST tuple types. Note: inner, leaf, and dead tuple structs
  220. * must have the same tupstate field in the same position! Real inner and
  221. * leaf tuples always have tupstate = LIVE; if the state is something else,
  222. * use the SpGistDeadTuple struct to inspect the tuple.
  223. */
  224. /* values of tupstate (see README for more info) */
  225. #define SPGIST_LIVE 0 /* normal live tuple (either inner or leaf) */
  226. #define SPGIST_REDIRECT 1 /* temporary redirection placeholder */
  227. #define SPGIST_DEAD 2 /* dead, cannot be removed because of links */
  228. #define SPGIST_PLACEHOLDER 3 /* placeholder, used to preserve offsets */
  229. /*
  230. * SPGiST inner tuple: list of "nodes" that subdivide a set of tuples
  231. *
  232. * Inner tuple layout:
  233. * header/optional prefix/array of nodes, which are SpGistNodeTuples
  234. *
  235. * size and prefixSize must be multiples of MAXALIGN
  236. *
  237. * If the prefix datum is of a pass-by-value type, it is stored in its
  238. * Datum representation, that is its on-disk representation is of length
  239. * sizeof(Datum). This is a fairly unfortunate choice, because in no other
  240. * place does Postgres use Datum as an on-disk representation; it creates
  241. * an unnecessary incompatibility between 32-bit and 64-bit builds. But the
  242. * compatibility loss is mostly theoretical since MAXIMUM_ALIGNOF typically
  243. * differs between such builds, too. Anyway we're stuck with it now.
  244. */
  245. typedef struct SpGistInnerTupleData
  246. {
  247. unsigned int tupstate:2, /* LIVE/REDIRECT/DEAD/PLACEHOLDER */
  248. allTheSame:1, /* all nodes in tuple are equivalent */
  249. nNodes:13, /* number of nodes within inner tuple */
  250. prefixSize:16; /* size of prefix, or 0 if none */
  251. uint16 size; /* total size of inner tuple */
  252. /* On most machines there will be a couple of wasted bytes here */
  253. /* prefix datum follows, then nodes */
  254. } SpGistInnerTupleData;
  255. typedef SpGistInnerTupleData *SpGistInnerTuple;
  256. /* these must match largest values that fit in bit fields declared above */
  257. #define SGITMAXNNODES 0x1FFF
  258. #define SGITMAXPREFIXSIZE 0xFFFF
  259. #define SGITMAXSIZE 0xFFFF
  260. #define SGITHDRSZ MAXALIGN(sizeof(SpGistInnerTupleData))
  261. #define _SGITDATA(x) (((char *) (x)) + SGITHDRSZ)
  262. #define SGITDATAPTR(x) ((x)->prefixSize ? _SGITDATA(x) : NULL)
  263. #define SGITDATUM(x, s) ((x)->prefixSize ? \
  264. ((s)->attPrefixType.attbyval ? \
  265. *(Datum *) _SGITDATA(x) : \
  266. PointerGetDatum(_SGITDATA(x))) \
  267. : (Datum) 0)
  268. #define SGITNODEPTR(x) ((SpGistNodeTuple) (_SGITDATA(x) + (x)->prefixSize))
  269. /* Macro for iterating through the nodes of an inner tuple */
  270. #define SGITITERATE(x, i, nt) \
  271. for ((i) = 0, (nt) = SGITNODEPTR(x); \
  272. (i) < (x)->nNodes; \
  273. (i)++, (nt) = (SpGistNodeTuple) (((char *) (nt)) + IndexTupleSize(nt)))
  274. /*
  275. * SPGiST node tuple: one node within an inner tuple
  276. *
  277. * Node tuples use the same header as ordinary Postgres IndexTuples, but
  278. * we do not use a null bitmap, because we know there is only one column
  279. * so the INDEX_NULL_MASK bit suffices. Also, pass-by-value datums are
  280. * stored in Datum form, the same convention as for inner tuple prefixes.
  281. */
  282. typedef IndexTupleData SpGistNodeTupleData;
  283. typedef SpGistNodeTupleData *SpGistNodeTuple;
  284. #define SGNTHDRSZ MAXALIGN(sizeof(SpGistNodeTupleData))
  285. #define SGNTDATAPTR(x) (((char *) (x)) + SGNTHDRSZ)
  286. #define SGNTDATUM(x, s) ((s)->attLabelType.attbyval ? \
  287. *(Datum *) SGNTDATAPTR(x) : \
  288. PointerGetDatum(SGNTDATAPTR(x)))
  289. /*
  290. * SPGiST leaf tuple: carries a leaf datum and a heap tuple TID,
  291. * and optionally some "included" columns.
  292. *
  293. * In the simplest case, the leaf datum is the same as the indexed value;
  294. * but it could also be a suffix or some other sort of delta that permits
  295. * reconstruction given knowledge of the prefix path traversed to get here.
  296. * Any included columns are stored without modification.
  297. *
  298. * A nulls bitmap is present if there are included columns AND any of the
  299. * datums are NULL. We do not need a nulls bitmap for the case of a null
  300. * leaf datum without included columns, as we can infer whether the leaf
  301. * datum is null from whether the tuple is stored on a nulls page. (This
  302. * provision is mostly for backwards compatibility, but it does save space
  303. * on 32-bit machines.) As with other PG index tuple designs, if the nulls
  304. * bitmap exists then it's of size INDEX_MAX_KEYS bits regardless of the
  305. * actual number of attributes. For the usual choice of INDEX_MAX_KEYS,
  306. * this costs nothing because of alignment considerations.
  307. *
  308. * The size field is wider than could possibly be needed for an on-disk leaf
  309. * tuple, but this allows us to form leaf tuples even when the datum is too
  310. * wide to be stored immediately, and it costs nothing because of alignment
  311. * considerations.
  312. *
  313. * t_info holds the nextOffset field (14 bits wide, enough for supported
  314. * page sizes) plus the has-nulls-bitmap flag bit; another flag bit is free.
  315. *
  316. * Normally, nextOffset links to the next tuple belonging to the same parent
  317. * node (which must be on the same page), or it's 0 if there is no next tuple.
  318. * But when the root page is a leaf page, we don't chain its tuples,
  319. * so nextOffset is always 0 on the root.
  320. *
  321. * size must be a multiple of MAXALIGN; also, it must be at least SGDTSIZE
  322. * so that the tuple can be converted to REDIRECT status later. (This
  323. * restriction only adds bytes for a NULL leaf datum stored on a 32-bit
  324. * machine; otherwise alignment restrictions force it anyway.)
  325. */
  326. typedef struct SpGistLeafTupleData
  327. {
  328. unsigned int tupstate:2, /* LIVE/REDIRECT/DEAD/PLACEHOLDER */
  329. size:30; /* large enough for any palloc'able value */
  330. uint16 t_info; /* nextOffset, which links to the next tuple
  331. * in chain, plus two flag bits */
  332. ItemPointerData heapPtr; /* TID of represented heap tuple */
  333. /* nulls bitmap follows if the flag bit for it is set */
  334. /* leaf datum, then any included datums, follows on a MAXALIGN boundary */
  335. } SpGistLeafTupleData;
  336. /* Macros to access nextOffset and bit fields inside t_info */
  337. #define SGLT_GET_NEXTOFFSET(spgLeafTuple) \
  338. ((spgLeafTuple)->t_info & 0x3FFF)
  339. #define SGLT_GET_HASNULLMASK(spgLeafTuple) \
  340. (((spgLeafTuple)->t_info & 0x8000) ? true : false)
  341. #define SGLT_SET_NEXTOFFSET(spgLeafTuple, offsetNumber) \
  342. ((spgLeafTuple)->t_info = \
  343. ((spgLeafTuple)->t_info & 0xC000) | ((offsetNumber) & 0x3FFF))
  344. #define SGLT_SET_HASNULLMASK(spgLeafTuple, hasnulls) \
  345. ((spgLeafTuple)->t_info = \
  346. ((spgLeafTuple)->t_info & 0x7FFF) | ((hasnulls) ? 0x8000 : 0))
  347. #define SGLTHDRSZ(hasnulls) \
  348. ((hasnulls) ? MAXALIGN(sizeof(SpGistLeafTupleData) + \
  349. sizeof(IndexAttributeBitMapData)) : \
  350. MAXALIGN(sizeof(SpGistLeafTupleData)))
  351. #define SGLTDATAPTR(x) (((char *) (x)) + SGLTHDRSZ(SGLT_GET_HASNULLMASK(x)))
  352. #define SGLTDATUM(x, s) fetch_att(SGLTDATAPTR(x), \
  353. (s)->attLeafType.attbyval, \
  354. (s)->attLeafType.attlen)
  355. /*
  356. * SPGiST dead tuple: declaration for examining non-live tuples
  357. *
  358. * The tupstate field of this struct must match those of regular inner and
  359. * leaf tuples, and its size field must match a leaf tuple's.
  360. * Also, the pointer field must be in the same place as a leaf tuple's heapPtr
  361. * field, to satisfy some Asserts that we make when replacing a leaf tuple
  362. * with a dead tuple.
  363. * We don't use t_info, but it's needed to align the pointer field.
  364. * pointer and xid are only valid when tupstate = REDIRECT.
  365. */
  366. typedef struct SpGistDeadTupleData
  367. {
  368. unsigned int tupstate:2, /* LIVE/REDIRECT/DEAD/PLACEHOLDER */
  369. size:30;
  370. uint16 t_info; /* not used in dead tuples */
  371. ItemPointerData pointer; /* redirection inside index */
  372. TransactionId xid; /* ID of xact that inserted this tuple */
  373. } SpGistDeadTupleData;
  374. typedef SpGistDeadTupleData *SpGistDeadTuple;
  375. #define SGDTSIZE MAXALIGN(sizeof(SpGistDeadTupleData))
  376. /*
  377. * Macros for doing free-space calculations. Note that when adding up the
  378. * space needed for tuples, we always consider each tuple to need the tuple's
  379. * size plus sizeof(ItemIdData) (for the line pointer). This works correctly
  380. * so long as tuple sizes are always maxaligned.
  381. */
  382. /* Page capacity after allowing for fixed header and special space */
  383. #define SPGIST_PAGE_CAPACITY \
  384. MAXALIGN_DOWN(BLCKSZ - \
  385. SizeOfPageHeaderData - \
  386. MAXALIGN(sizeof(SpGistPageOpaqueData)))
  387. /*
  388. * Compute free space on page, assuming that up to n placeholders can be
  389. * recycled if present (n should be the number of tuples to be inserted)
  390. */
  391. #define SpGistPageGetFreeSpace(p, n) \
  392. (PageGetExactFreeSpace(p) + \
  393. Min(SpGistPageGetOpaque(p)->nPlaceholder, n) * \
  394. (SGDTSIZE + sizeof(ItemIdData)))
  395. /*
  396. * XLOG stuff
  397. */
  398. #define STORE_STATE(s, d) \
  399. do { \
  400. (d).myXid = (s)->myXid; \
  401. (d).isBuild = (s)->isBuild; \
  402. } while(0)
  403. /*
  404. * The "flags" argument for SpGistGetBuffer should be either GBUF_LEAF to
  405. * get a leaf page, or GBUF_INNER_PARITY(blockNumber) to get an inner
  406. * page in the same triple-parity group as the specified block number.
  407. * (Typically, this should be GBUF_INNER_PARITY(parentBlockNumber + 1)
  408. * to follow the rule described in spgist/README.)
  409. * In addition, GBUF_NULLS can be OR'd in to get a page for storage of
  410. * null-valued tuples.
  411. *
  412. * Note: these flag values are used as indexes into lastUsedPages.
  413. */
  414. #define GBUF_LEAF 0x03
  415. #define GBUF_INNER_PARITY(x) ((x) % 3)
  416. #define GBUF_NULLS 0x04
  417. #define GBUF_PARITY_MASK 0x03
  418. #define GBUF_REQ_LEAF(flags) (((flags) & GBUF_PARITY_MASK) == GBUF_LEAF)
  419. #define GBUF_REQ_NULLS(flags) ((flags) & GBUF_NULLS)
  420. /* spgutils.c */
  421. /* reloption parameters */
  422. #define SPGIST_MIN_FILLFACTOR 10
  423. #define SPGIST_DEFAULT_FILLFACTOR 80
  424. extern SpGistCache *spgGetCache(Relation index);
  425. extern TupleDesc getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType);
  426. extern void initSpGistState(SpGistState *state, Relation index);
  427. extern Buffer SpGistNewBuffer(Relation index);
  428. extern void SpGistUpdateMetaPage(Relation index);
  429. extern Buffer SpGistGetBuffer(Relation index, int flags,
  430. int needSpace, bool *isNew);
  431. extern void SpGistSetLastUsedPage(Relation index, Buffer buffer);
  432. extern void SpGistInitPage(Page page, uint16 f);
  433. extern void SpGistInitBuffer(Buffer b, uint16 f);
  434. extern void SpGistInitMetapage(Page page);
  435. extern unsigned int SpGistGetInnerTypeSize(SpGistTypeDesc *att, Datum datum);
  436. extern Size SpGistGetLeafTupleSize(TupleDesc tupleDescriptor,
  437. Datum *datums, bool *isnulls);
  438. extern SpGistLeafTuple spgFormLeafTuple(SpGistState *state,
  439. ItemPointer heapPtr,
  440. Datum *datums, bool *isnulls);
  441. extern SpGistNodeTuple spgFormNodeTuple(SpGistState *state,
  442. Datum label, bool isnull);
  443. extern SpGistInnerTuple spgFormInnerTuple(SpGistState *state,
  444. bool hasPrefix, Datum prefix,
  445. int nNodes, SpGistNodeTuple *nodes);
  446. extern SpGistDeadTuple spgFormDeadTuple(SpGistState *state, int tupstate,
  447. BlockNumber blkno, OffsetNumber offnum);
  448. extern void spgDeformLeafTuple(SpGistLeafTuple tup, TupleDesc tupleDescriptor,
  449. Datum *datums, bool *isnulls,
  450. bool keyColumnIsNull);
  451. extern Datum *spgExtractNodeLabels(SpGistState *state,
  452. SpGistInnerTuple innerTuple);
  453. extern OffsetNumber SpGistPageAddNewItem(SpGistState *state, Page page,
  454. Item item, Size size,
  455. OffsetNumber *startOffset,
  456. bool errorOK);
  457. extern bool spgproperty(Oid index_oid, int attno,
  458. IndexAMProperty prop, const char *propname,
  459. bool *res, bool *isnull);
  460. /* spgdoinsert.c */
  461. extern void spgUpdateNodeLink(SpGistInnerTuple tup, int nodeN,
  462. BlockNumber blkno, OffsetNumber offset);
  463. extern void spgPageIndexMultiDelete(SpGistState *state, Page page,
  464. OffsetNumber *itemnos, int nitems,
  465. int firststate, int reststate,
  466. BlockNumber blkno, OffsetNumber offnum);
  467. extern bool spgdoinsert(Relation index, SpGistState *state,
  468. ItemPointer heapPtr, Datum *datums, bool *isnulls);
  469. /* spgproc.c */
  470. extern double *spg_key_orderbys_distances(Datum key, bool isLeaf,
  471. ScanKey orderbys, int norderbys);
  472. extern BOX *box_copy(BOX *orig);
  473. #endif /* SPGIST_PRIVATE_H */