1 /*-------------------------------------------------------------------------
2  *
3  * spgist.h
4  *	  Public header file for SP-GiST access method.
5  *
6  *
7  * Portions Copyright (c) 1996-2018, 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 	int			nkeys;			/* length of array */
140 
141 	Datum		reconstructedValue; /* value reconstructed at parent */
142 	void	   *traversalValue; /* opclass-specific traverse value */
143 	MemoryContext traversalMemoryContext;	/* put new traverse values here */
144 	int			level;			/* current level (counting from zero) */
145 	bool		returnData;		/* original data must be returned? */
146 
147 	/* Data from current inner tuple */
148 	bool		allTheSame;		/* tuple is marked all-the-same? */
149 	bool		hasPrefix;		/* tuple has a prefix? */
150 	Datum		prefixDatum;	/* if so, the prefix value */
151 	int			nNodes;			/* number of nodes in the inner tuple */
152 	Datum	   *nodeLabels;		/* node label values (NULL if none) */
153 } spgInnerConsistentIn;
154 
155 typedef struct spgInnerConsistentOut
156 {
157 	int			nNodes;			/* number of child nodes to be visited */
158 	int		   *nodeNumbers;	/* their indexes in the node array */
159 	int		   *levelAdds;		/* increment level by this much for each */
160 	Datum	   *reconstructedValues;	/* associated reconstructed values */
161 	void	  **traversalValues;	/* opclass-specific traverse values */
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 	int			nkeys;			/* length of array */
171 
172 	Datum		reconstructedValue; /* value reconstructed at parent */
173 	void	   *traversalValue; /* opclass-specific traverse value */
174 	int			level;			/* current level (counting from zero) */
175 	bool		returnData;		/* original data must be returned? */
176 
177 	Datum		leafDatum;		/* datum in leaf tuple */
178 } spgLeafConsistentIn;
179 
180 typedef struct spgLeafConsistentOut
181 {
182 	Datum		leafValue;		/* reconstructed original data, if any */
183 	bool		recheck;		/* set true if operator must be rechecked */
184 } spgLeafConsistentOut;
185 
186 
187 /* spgutils.c */
188 extern bytea *spgoptions(Datum reloptions, bool validate);
189 
190 /* spginsert.c */
191 extern IndexBuildResult *spgbuild(Relation heap, Relation index,
192 		 struct IndexInfo *indexInfo);
193 extern void spgbuildempty(Relation index);
194 extern bool spginsert(Relation index, Datum *values, bool *isnull,
195 		  ItemPointer ht_ctid, Relation heapRel,
196 		  IndexUniqueCheck checkUnique,
197 		  struct IndexInfo *indexInfo);
198 
199 /* spgscan.c */
200 extern IndexScanDesc spgbeginscan(Relation rel, int keysz, int orderbysz);
201 extern void spgendscan(IndexScanDesc scan);
202 extern void spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
203 		  ScanKey orderbys, int norderbys);
204 extern int64 spggetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
205 extern bool spggettuple(IndexScanDesc scan, ScanDirection dir);
206 extern bool spgcanreturn(Relation index, int attno);
207 
208 /* spgvacuum.c */
209 extern IndexBulkDeleteResult *spgbulkdelete(IndexVacuumInfo *info,
210 			  IndexBulkDeleteResult *stats,
211 			  IndexBulkDeleteCallback callback,
212 			  void *callback_state);
213 extern IndexBulkDeleteResult *spgvacuumcleanup(IndexVacuumInfo *info,
214 				 IndexBulkDeleteResult *stats);
215 
216 /* spgvalidate.c */
217 extern bool spgvalidate(Oid opclassoid);
218 
219 #endif							/* SPGIST_H */
220