1 /*-------------------------------------------------------------------------
4 * common declarations for the GiST access method code.
7 * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * $PostgreSQL: pgsql/src/include/access/gist.h,v 1.41 2004/08/29 04:13:03 momjian Exp $
12 *-------------------------------------------------------------------------
17 #include "access/itup.h"
18 #include "access/relscan.h"
19 #include "access/sdir.h"
20 #include "access/xlog.h"
23 * You can have as many strategies as you please in GiSTs,
24 * as long as your consistent method can handle them.
25 * The system doesn't really care what they are.
27 #define GISTNStrategies 100
30 * amproc indexes for GiST indexes.
32 #define GIST_CONSISTENT_PROC 1
33 #define GIST_UNION_PROC 2
34 #define GIST_COMPRESS_PROC 3
35 #define GIST_DECOMPRESS_PROC 4
36 #define GIST_PENALTY_PROC 5
37 #define GIST_PICKSPLIT_PROC 6
38 #define GIST_EQUAL_PROC 7
43 * Page opaque data in a GiST index page.
45 #define F_LEAF (1 << 0)
47 typedef struct GISTPageOpaqueData
52 typedef GISTPageOpaqueData *GISTPageOpaque;
54 #define GIST_LEAF(entry) (((GISTPageOpaque) PageGetSpecialPointer((entry)->page))->flags & F_LEAF)
57 * When we descend a tree, we keep a stack of parent pointers.
59 typedef struct GISTSTACK
61 struct GISTSTACK *gs_parent;
62 OffsetNumber gs_child;
66 typedef struct GISTSTATE
68 FmgrInfo consistentFn[INDEX_MAX_KEYS];
69 FmgrInfo unionFn[INDEX_MAX_KEYS];
70 FmgrInfo compressFn[INDEX_MAX_KEYS];
71 FmgrInfo decompressFn[INDEX_MAX_KEYS];
72 FmgrInfo penaltyFn[INDEX_MAX_KEYS];
73 FmgrInfo picksplitFn[INDEX_MAX_KEYS];
74 FmgrInfo equalFn[INDEX_MAX_KEYS];
79 #define isAttByVal( gs, anum ) (gs)->tupdesc->attrs[anum]->attbyval
82 * When we're doing a scan, we need to keep track of the parent stack
83 * for the marked and current items.
85 typedef struct GISTScanOpaqueData
87 struct GISTSTACK *s_stack;
88 struct GISTSTACK *s_markstk;
90 struct GISTSTATE *giststate;
93 typedef GISTScanOpaqueData *GISTScanOpaque;
96 * When we're doing a scan and updating a tree at the same time, the
97 * updates may affect the scan. We use the flags entry of the scan's
98 * opaque space to record our actual position in response to updates
99 * that we can't handle simply by adjusting pointers.
101 #define GS_CURBEFORE ((uint16) (1 << 0))
102 #define GS_MRKBEFORE ((uint16) (1 << 1))
104 /* root page of a gist */
108 * When we update a relation on which we're doing a scan, we need to
109 * check the scan and fix it if the update affected any of the pages it
110 * touches. Otherwise, we can miss records that we should see. The only
111 * times we need to do this are for deletions and splits. See the code in
112 * gistscan.c for how the scan is fixed. These two constants tell us what sort
113 * of operation changed the index.
116 #define GISTOP_SPLIT 1
119 * This is the Split Vector to be returned by the PickSplit method.
121 typedef struct GIST_SPLITVEC
123 OffsetNumber *spl_left; /* array of entries that go left */
124 int spl_nleft; /* size of this array */
125 Datum spl_ldatum; /* Union of keys in spl_left */
126 Datum spl_lattr[INDEX_MAX_KEYS]; /* Union of subkeys in
128 int spl_lattrsize[INDEX_MAX_KEYS];
129 bool spl_lisnull[INDEX_MAX_KEYS];
131 OffsetNumber *spl_right; /* array of entries that go right */
132 int spl_nright; /* size of the array */
133 Datum spl_rdatum; /* Union of keys in spl_right */
134 Datum spl_rattr[INDEX_MAX_KEYS]; /* Union of subkeys in
136 int spl_rattrsize[INDEX_MAX_KEYS];
137 bool spl_risnull[INDEX_MAX_KEYS];
140 int *spl_ngrp; /* number in each group */
141 char *spl_grpflag; /* flags of each group */
145 * An entry on a GiST node. Contains the key, as well as
146 * its own location (rel,page,offset) which can supply the matching
147 * pointer. The size of the key is in bytes, and leafkey is a flag to
148 * tell us if the entry is in a leaf node.
150 typedef struct GISTENTRY
162 * Vector of GISTENTRY struct's, user-defined
163 * methods union andpick split takes it as one of args
167 int32 n; /* number of elements */
171 #define GEVHDRSZ ( offsetof(GistEntryVector, vector[0]) )
174 * macro to initialize a GISTENTRY
176 #define gistentryinit(e, k, r, pg, o, b, l) \
177 do { (e).key = (k); (e).rel = (r); (e).page = (pg); \
178 (e).offset = (o); (e).bytes = (b); (e).leafkey = (l); } while (0)
181 extern Datum gistbuild(PG_FUNCTION_ARGS);
182 extern Datum gistinsert(PG_FUNCTION_ARGS);
183 extern Datum gistbulkdelete(PG_FUNCTION_ARGS);
184 extern void _gistdump(Relation r);
185 extern void gistfreestack(GISTSTACK *s);
186 extern void initGISTstate(GISTSTATE *giststate, Relation index);
187 extern void freeGISTstate(GISTSTATE *giststate);
188 extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
189 Datum k, Relation r, Page pg, OffsetNumber o,
190 int b, bool l, bool isNull);
192 extern void gist_redo(XLogRecPtr lsn, XLogRecord *record);
193 extern void gist_undo(XLogRecPtr lsn, XLogRecord *record);
194 extern void gist_desc(char *buf, uint8 xl_info, char *rec);
197 extern Datum gistgettuple(PG_FUNCTION_ARGS);