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