1
/*-------------------------------------------------------------------------
4
* The public API for GiST indexes. This API is exposed to
5
* individuals implementing GiST indexes, so backward-incompatible
6
* changes should be made with care.
9
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
10
* Portions Copyright (c) 1994, Regents of the University of California
12
* src/include/access/gist.h
14
*-------------------------------------------------------------------------
19
#include "access/xlog.h"
20
#include "access/xlogdefs.h"
21
#include "storage/block.h"
22
#include "storage/bufpage.h"
23
#include "utils/relcache.h"
26
* amproc indexes for GiST indexes.
28
#define GIST_CONSISTENT_PROC 1
29
#define GIST_UNION_PROC 2
30
#define GIST_COMPRESS_PROC 3
31
#define GIST_DECOMPRESS_PROC 4
32
#define GIST_PENALTY_PROC 5
33
#define GIST_PICKSPLIT_PROC 6
34
#define GIST_EQUAL_PROC 7
35
#define GIST_DISTANCE_PROC 8
39
* strategy numbers for GiST opclasses that want to implement the old
42
#define RTLeftStrategyNumber 1
43
#define RTOverLeftStrategyNumber 2
44
#define RTOverlapStrategyNumber 3
45
#define RTOverRightStrategyNumber 4
46
#define RTRightStrategyNumber 5
47
#define RTSameStrategyNumber 6
48
#define RTContainsStrategyNumber 7 /* for @> */
49
#define RTContainedByStrategyNumber 8 /* for <@ */
50
#define RTOverBelowStrategyNumber 9
51
#define RTBelowStrategyNumber 10
52
#define RTAboveStrategyNumber 11
53
#define RTOverAboveStrategyNumber 12
54
#define RTOldContainsStrategyNumber 13 /* for old spelling of @> */
55
#define RTOldContainedByStrategyNumber 14 /* for old spelling of <@ */
56
#define RTKNNSearchStrategyNumber 15
59
* Page opaque data in a GiST index page.
61
#define F_LEAF (1 << 0) /* leaf page */
62
#define F_DELETED (1 << 1) /* the page has been deleted */
63
#define F_TUPLES_DELETED (1 << 2) /* some tuples on the page are dead */
64
#define F_FOLLOW_RIGHT (1 << 3) /* page to the right has no downlink */
66
typedef XLogRecPtr GistNSN;
68
typedef struct GISTPageOpaqueData
70
GistNSN nsn; /* this value must change on page split */
71
BlockNumber rightlink; /* next page if any */
72
uint16 flags; /* see bit definitions above */
73
uint16 gist_page_id; /* for identification of GiST indexes */
76
typedef GISTPageOpaqueData *GISTPageOpaque;
79
* The page ID is for the convenience of pg_filedump and similar utilities,
80
* which otherwise would have a hard time telling pages of different index
81
* types apart. It should be the last 2 bytes on the page. This is more or
82
* less "free" due to alignment considerations.
84
#define GIST_PAGE_ID 0xFF81
87
* This is the Split Vector to be returned by the PickSplit method.
88
* PickSplit should check spl_(r|l)datum_exists. If it is 'true',
89
* that corresponding spl_(r|l)datum already defined and
90
* PickSplit should use that value. PickSplit should always set
91
* spl_(r|l)datum_exists to false: GiST will check value to
92
* control supportng this feature by PickSplit...
94
typedef struct GIST_SPLITVEC
96
OffsetNumber *spl_left; /* array of entries that go left */
97
int spl_nleft; /* size of this array */
98
Datum spl_ldatum; /* Union of keys in spl_left */
99
bool spl_ldatum_exists; /* true, if spl_ldatum already exists. */
101
OffsetNumber *spl_right; /* array of entries that go right */
102
int spl_nright; /* size of the array */
103
Datum spl_rdatum; /* Union of keys in spl_right */
104
bool spl_rdatum_exists; /* true, if spl_rdatum already exists. */
108
* An entry on a GiST node. Contains the key, as well as its own
109
* location (rel,page,offset) which can supply the matching pointer.
110
* leafkey is a flag to tell us if the entry is in a leaf node.
112
typedef struct GISTENTRY
121
#define GistPageGetOpaque(page) ( (GISTPageOpaque) PageGetSpecialPointer(page) )
123
#define GistPageIsLeaf(page) ( GistPageGetOpaque(page)->flags & F_LEAF)
124
#define GIST_LEAF(entry) (GistPageIsLeaf((entry)->page))
125
#define GistPageSetLeaf(page) ( GistPageGetOpaque(page)->flags |= F_LEAF)
126
#define GistPageSetNonLeaf(page) ( GistPageGetOpaque(page)->flags &= ~F_LEAF)
128
#define GistPageIsDeleted(page) ( GistPageGetOpaque(page)->flags & F_DELETED)
129
#define GistPageSetDeleted(page) ( GistPageGetOpaque(page)->flags |= F_DELETED)
130
#define GistPageSetNonDeleted(page) ( GistPageGetOpaque(page)->flags &= ~F_DELETED)
132
#define GistTuplesDeleted(page) ( GistPageGetOpaque(page)->flags & F_TUPLES_DELETED)
133
#define GistMarkTuplesDeleted(page) ( GistPageGetOpaque(page)->flags |= F_TUPLES_DELETED)
134
#define GistClearTuplesDeleted(page) ( GistPageGetOpaque(page)->flags &= ~F_TUPLES_DELETED)
136
#define GistFollowRight(page) ( GistPageGetOpaque(page)->flags & F_FOLLOW_RIGHT)
137
#define GistMarkFollowRight(page) ( GistPageGetOpaque(page)->flags |= F_FOLLOW_RIGHT)
138
#define GistClearFollowRight(page) ( GistPageGetOpaque(page)->flags &= ~F_FOLLOW_RIGHT)
141
* Vector of GISTENTRY structs; user-defined methods union and picksplit
142
* take it as one of their arguments
146
int32 n; /* number of elements */
147
GISTENTRY vector[1]; /* variable-length array */
150
#define GEVHDRSZ (offsetof(GistEntryVector, vector))
153
* macro to initialize a GISTENTRY
155
#define gistentryinit(e, k, r, pg, o, l) \
156
do { (e).key = (k); (e).rel = (r); (e).page = (pg); \
157
(e).offset = (o); (e).leafkey = (l); } while (0)