PostgreSQL Source Code: src/include/access/spgist_private.h Source File

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

AltStyle によって変換されたページ (->オリジナル) /