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