1 /*-------------------------------------------------------------------------
2  *
3  * spgist.h
4  *	  Public header file for SP-GiST access method.
5  *
6  *
7  * Portions Copyright (c) 1996-2017, 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 upper-level inner tuple with one child tuple */
94 			bool		prefixHasPrefix;	/* tuple should have a prefix? */
95 			Datum		prefixPrefixDatum;	/* if so, its value */
96 			int			prefixNNodes;	/* number of nodes */
97 			Datum	   *prefixNodeLabels;	/* their labels (or NULL for no
98 											 * labels) */
99 			int			childNodeN; /* which node gets child tuple */
100 
101 			/* Info to form new lower-level inner tuple with all old nodes */
102 			bool		postfixHasPrefix;	/* tuple should have a prefix? */
103 			Datum		postfixPrefixDatum; /* if so, its value */
104 		}			splitTuple;
105 	}			result;
106 } spgChooseOut;
107 
108 /*
109  * Argument structs for spg_picksplit method
110  */
111 typedef struct spgPickSplitIn
112 {
113 	int			nTuples;		/* number of leaf tuples */
114 	Datum	   *datums;			/* their datums (array of length nTuples) */
115 	int			level;			/* current level (counting from zero) */
116 } spgPickSplitIn;
117 
118 typedef struct spgPickSplitOut
119 {
120 	bool		hasPrefix;		/* new inner tuple should have a prefix? */
121 	Datum		prefixDatum;	/* if so, its value */
122 
123 	int			nNodes;			/* number of nodes for new inner tuple */
124 	Datum	   *nodeLabels;		/* their labels (or NULL for no labels) */
125 
126 	int		   *mapTuplesToNodes;	/* node index for each leaf tuple */
127 	Datum	   *leafTupleDatums;	/* datum to store in each new leaf tuple */
128 } spgPickSplitOut;
129 
130 /*
131  * Argument structs for spg_inner_consistent method
132  */
133 typedef struct spgInnerConsistentIn
134 {
135 	ScanKey		scankeys;		/* array of operators and comparison values */
136 	int			nkeys;			/* length of array */
137 
138 	Datum		reconstructedValue; /* value reconstructed at parent */
139 	void	   *traversalValue; /* opclass-specific traverse value */
140 	MemoryContext traversalMemoryContext;	/* put new traverse values here */
141 	int			level;			/* current level (counting from zero) */
142 	bool		returnData;		/* original data must be returned? */
143 
144 	/* Data from current inner tuple */
145 	bool		allTheSame;		/* tuple is marked all-the-same? */
146 	bool		hasPrefix;		/* tuple has a prefix? */
147 	Datum		prefixDatum;	/* if so, the prefix value */
148 	int			nNodes;			/* number of nodes in the inner tuple */
149 	Datum	   *nodeLabels;		/* node label values (NULL if none) */
150 } spgInnerConsistentIn;
151 
152 typedef struct spgInnerConsistentOut
153 {
154 	int			nNodes;			/* number of child nodes to be visited */
155 	int		   *nodeNumbers;	/* their indexes in the node array */
156 	int		   *levelAdds;		/* increment level by this much for each */
157 	Datum	   *reconstructedValues;	/* associated reconstructed values */
158 	void	  **traversalValues;	/* opclass-specific traverse values */
159 } spgInnerConsistentOut;
160 
161 /*
162  * Argument structs for spg_leaf_consistent method
163  */
164 typedef struct spgLeafConsistentIn
165 {
166 	ScanKey		scankeys;		/* array of operators and comparison values */
167 	int			nkeys;			/* length of array */
168 
169 	Datum		reconstructedValue; /* value reconstructed at parent */
170 	void	   *traversalValue; /* opclass-specific traverse value */
171 	int			level;			/* current level (counting from zero) */
172 	bool		returnData;		/* original data must be returned? */
173 
174 	Datum		leafDatum;		/* datum in leaf tuple */
175 } spgLeafConsistentIn;
176 
177 typedef struct spgLeafConsistentOut
178 {
179 	Datum		leafValue;		/* reconstructed original data, if any */
180 	bool		recheck;		/* set true if operator must be rechecked */
181 } spgLeafConsistentOut;
182 
183 
184 /* spgutils.c */
185 extern bytea *spgoptions(Datum reloptions, bool validate);
186 
187 /* spginsert.c */
188 extern IndexBuildResult *spgbuild(Relation heap, Relation index,
189 		 struct IndexInfo *indexInfo);
190 extern void spgbuildempty(Relation index);
191 extern bool spginsert(Relation index, Datum *values, bool *isnull,
192 		  ItemPointer ht_ctid, Relation heapRel,
193 		  IndexUniqueCheck checkUnique,
194 		  struct IndexInfo *indexInfo);
195 
196 /* spgscan.c */
197 extern IndexScanDesc spgbeginscan(Relation rel, int keysz, int orderbysz);
198 extern void spgendscan(IndexScanDesc scan);
199 extern void spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
200 		  ScanKey orderbys, int norderbys);
201 extern int64 spggetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
202 extern bool spggettuple(IndexScanDesc scan, ScanDirection dir);
203 extern bool spgcanreturn(Relation index, int attno);
204 
205 /* spgvacuum.c */
206 extern IndexBulkDeleteResult *spgbulkdelete(IndexVacuumInfo *info,
207 			  IndexBulkDeleteResult *stats,
208 			  IndexBulkDeleteCallback callback,
209 			  void *callback_state);
210 extern IndexBulkDeleteResult *spgvacuumcleanup(IndexVacuumInfo *info,
211 				 IndexBulkDeleteResult *stats);
212 
213 /* spgvalidate.c */
214 extern bool spgvalidate(Oid opclassoid);
215 
216 #endif							/* SPGIST_H */
217