1 /*-------------------------------------------------------------------------
2  *
3  * spgist.h
4  *	  Public header file for SP-GiST access method.
5  *
6  *
7  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * src/include/access/spgist.h
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef SPGIST_H
15 #define SPGIST_H
16 
17 #include "access/amapi.h"
18 #include "access/xlogreader.h"
19 #include "fmgr.h"
20 #include "lib/stringinfo.h"
21 
22 
23 /* reloption parameters */
24 #define SPGIST_MIN_FILLFACTOR			10
25 #define SPGIST_DEFAULT_FILLFACTOR		80
26 
27 /* SPGiST opclass support function numbers */
28 #define SPGIST_CONFIG_PROC				1
29 #define SPGIST_CHOOSE_PROC				2
30 #define SPGIST_PICKSPLIT_PROC			3
31 #define SPGIST_INNER_CONSISTENT_PROC	4
32 #define SPGIST_LEAF_CONSISTENT_PROC		5
33 #define SPGISTNProc						5
34 
35 /*
36  * Argument structs for spg_config method
37  */
38 typedef struct spgConfigIn
39 {
40 	Oid			attType;		/* Data type to be indexed */
41 } spgConfigIn;
42 
43 typedef struct spgConfigOut
44 {
45 	Oid			prefixType;		/* Data type of inner-tuple prefixes */
46 	Oid			labelType;		/* Data type of inner-tuple node labels */
47 	bool		canReturnData;	/* Opclass can reconstruct original data */
48 	bool		longValuesOK;	/* Opclass can cope with values > 1 page */
49 } spgConfigOut;
50 
51 /*
52  * Argument structs for spg_choose method
53  */
54 typedef struct spgChooseIn
55 {
56 	Datum		datum;			/* original datum to be indexed */
57 	Datum		leafDatum;		/* current datum to be stored at leaf */
58 	int			level;			/* current level (counting from zero) */
59 
60 	/* Data from current inner tuple */
61 	bool		allTheSame;		/* tuple is marked all-the-same? */
62 	bool		hasPrefix;		/* tuple has a prefix? */
63 	Datum		prefixDatum;	/* if so, the prefix value */
64 	int			nNodes;			/* number of nodes in the inner tuple */
65 	Datum	   *nodeLabels;		/* node label values (NULL if none) */
66 } spgChooseIn;
67 
68 typedef enum spgChooseResultType
69 {
70 	spgMatchNode = 1,			/* descend into existing node */
71 	spgAddNode,					/* add a node to the inner tuple */
72 	spgSplitTuple				/* split inner tuple (change its prefix) */
73 } spgChooseResultType;
74 
75 typedef struct spgChooseOut
76 {
77 	spgChooseResultType resultType;		/* action code, see above */
78 	union
79 	{
80 		struct					/* results for spgMatchNode */
81 		{
82 			int			nodeN;	/* descend to this node (index from 0) */
83 			int			levelAdd;		/* increment level by this much */
84 			Datum		restDatum;		/* new leaf datum */
85 		}			matchNode;
86 		struct					/* results for spgAddNode */
87 		{
88 			Datum		nodeLabel;		/* new node's label */
89 			int			nodeN;	/* where to insert it (index from 0) */
90 		}			addNode;
91 		struct					/* results for spgSplitTuple */
92 		{
93 			/* Info to form new inner tuple with one node */
94 			bool		prefixHasPrefix;		/* tuple should have a prefix? */
95 			Datum		prefixPrefixDatum;		/* if so, its value */
96 			Datum		nodeLabel;		/* node's label */
97 
98 			/* Info to form new lower-level inner tuple with all old nodes */
99 			bool		postfixHasPrefix;		/* tuple should have a prefix? */
100 			Datum		postfixPrefixDatum;		/* if so, its value */
101 		}			splitTuple;
102 	}			result;
103 } spgChooseOut;
104 
105 /*
106  * Argument structs for spg_picksplit method
107  */
108 typedef struct spgPickSplitIn
109 {
110 	int			nTuples;		/* number of leaf tuples */
111 	Datum	   *datums;			/* their datums (array of length nTuples) */
112 	int			level;			/* current level (counting from zero) */
113 } spgPickSplitIn;
114 
115 typedef struct spgPickSplitOut
116 {
117 	bool		hasPrefix;		/* new inner tuple should have a prefix? */
118 	Datum		prefixDatum;	/* if so, its value */
119 
120 	int			nNodes;			/* number of nodes for new inner tuple */
121 	Datum	   *nodeLabels;		/* their labels (or NULL for no labels) */
122 
123 	int		   *mapTuplesToNodes;		/* node index for each leaf tuple */
124 	Datum	   *leafTupleDatums;	/* datum to store in each new leaf tuple */
125 } spgPickSplitOut;
126 
127 /*
128  * Argument structs for spg_inner_consistent method
129  */
130 typedef struct spgInnerConsistentIn
131 {
132 	ScanKey		scankeys;		/* array of operators and comparison values */
133 	int			nkeys;			/* length of array */
134 
135 	Datum		reconstructedValue;		/* value reconstructed at parent */
136 	void	   *traversalValue; /* opclass-specific traverse value */
137 	MemoryContext traversalMemoryContext;
138 	int			level;			/* current level (counting from zero) */
139 	bool		returnData;		/* original data must be returned? */
140 
141 	/* Data from current inner tuple */
142 	bool		allTheSame;		/* tuple is marked all-the-same? */
143 	bool		hasPrefix;		/* tuple has a prefix? */
144 	Datum		prefixDatum;	/* if so, the prefix value */
145 	int			nNodes;			/* number of nodes in the inner tuple */
146 	Datum	   *nodeLabels;		/* node label values (NULL if none) */
147 } spgInnerConsistentIn;
148 
149 typedef struct spgInnerConsistentOut
150 {
151 	int			nNodes;			/* number of child nodes to be visited */
152 	int		   *nodeNumbers;	/* their indexes in the node array */
153 	int		   *levelAdds;		/* increment level by this much for each */
154 	Datum	   *reconstructedValues;	/* associated reconstructed values */
155 	void	  **traversalValues;	/* opclass-specific traverse values */
156 } spgInnerConsistentOut;
157 
158 /*
159  * Argument structs for spg_leaf_consistent method
160  */
161 typedef struct spgLeafConsistentIn
162 {
163 	ScanKey		scankeys;		/* array of operators and comparison values */
164 	int			nkeys;			/* length of array */
165 
166 	void	   *traversalValue; /* opclass-specific traverse value */
167 	Datum		reconstructedValue;		/* value reconstructed at parent */
168 	int			level;			/* current level (counting from zero) */
169 	bool		returnData;		/* original data must be returned? */
170 
171 	Datum		leafDatum;		/* datum in leaf tuple */
172 } spgLeafConsistentIn;
173 
174 typedef struct spgLeafConsistentOut
175 {
176 	Datum		leafValue;		/* reconstructed original data, if any */
177 	bool		recheck;		/* set true if operator must be rechecked */
178 } spgLeafConsistentOut;
179 
180 
181 /* spgutils.c */
182 extern Datum spghandler(PG_FUNCTION_ARGS);
183 extern bytea *spgoptions(Datum reloptions, bool validate);
184 
185 /* spginsert.c */
186 extern IndexBuildResult *spgbuild(Relation heap, Relation index,
187 		 struct IndexInfo *indexInfo);
188 extern void spgbuildempty(Relation index);
189 extern bool spginsert(Relation index, Datum *values, bool *isnull,
190 		  ItemPointer ht_ctid, Relation heapRel,
191 		  IndexUniqueCheck checkUnique);
192 
193 /* spgscan.c */
194 extern IndexScanDesc spgbeginscan(Relation rel, int keysz, int orderbysz);
195 extern void spgendscan(IndexScanDesc scan);
196 extern void spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
197 		  ScanKey orderbys, int norderbys);
198 extern int64 spggetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
199 extern bool spggettuple(IndexScanDesc scan, ScanDirection dir);
200 extern bool spgcanreturn(Relation index, int attno);
201 
202 /* spgvacuum.c */
203 extern IndexBulkDeleteResult *spgbulkdelete(IndexVacuumInfo *info,
204 			  IndexBulkDeleteResult *stats,
205 			  IndexBulkDeleteCallback callback,
206 			  void *callback_state);
207 extern IndexBulkDeleteResult *spgvacuumcleanup(IndexVacuumInfo *info,
208 				 IndexBulkDeleteResult *stats);
209 
210 /* spgvalidate.c */
211 extern bool spgvalidate(Oid opclassoid);
212 
213 /* spgxlog.c */
214 extern void spg_redo(XLogReaderState *record);
215 extern void spg_desc(StringInfo buf, XLogReaderState *record);
216 extern const char *spg_identify(uint8 info);
217 extern void spg_xlog_startup(void);
218 extern void spg_xlog_cleanup(void);
219 
220 #endif   /* SPGIST_H */
221