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