1 /* contrib/ltree/ltree.h */
2 
3 #ifndef __LTREE_H__
4 #define __LTREE_H__
5 
6 #include "fmgr.h"
7 #include "tsearch/ts_locale.h"
8 #include "utils/memutils.h"
9 
10 typedef struct
11 {
12 	uint16		len;
13 	char		name[FLEXIBLE_ARRAY_MEMBER];
14 } ltree_level;
15 
16 #define LEVEL_HDRSIZE	(offsetof(ltree_level,name))
17 #define LEVEL_NEXT(x)	( (ltree_level*)( ((char*)(x)) + MAXALIGN(((ltree_level*)(x))->len + LEVEL_HDRSIZE) ) )
18 
19 typedef struct
20 {
21 	int32		vl_len_;		/* varlena header (do not touch directly!) */
22 	uint16		numlevel;
23 	char		data[FLEXIBLE_ARRAY_MEMBER];
24 } ltree;
25 
26 #define LTREE_HDRSIZE	MAXALIGN( offsetof(ltree, data) )
27 #define LTREE_FIRST(x)	( (ltree_level*)( ((char*)(x))+LTREE_HDRSIZE ) )
28 #define LTREE_MAX_LEVELS	PG_UINT16_MAX	/* ltree.numlevel is uint16 */
29 
30 
31 /* lquery */
32 
33 typedef struct
34 {
35 	int32		val;
36 	uint16		len;
37 	uint8		flag;
38 	char		name[FLEXIBLE_ARRAY_MEMBER];
39 } lquery_variant;
40 
41 #define LVAR_HDRSIZE   MAXALIGN(offsetof(lquery_variant, name))
42 #define LVAR_NEXT(x)	( (lquery_variant*)( ((char*)(x)) + MAXALIGN(((lquery_variant*)(x))->len) + LVAR_HDRSIZE ) )
43 
44 #define LVAR_ANYEND 0x01
45 #define LVAR_INCASE 0x02
46 #define LVAR_SUBLEXEME	0x04
47 
48 typedef struct
49 {
50 	uint16		totallen;
51 	uint16		flag;
52 	uint16		numvar;
53 	uint16		low;
54 	uint16		high;
55 	char		variants[FLEXIBLE_ARRAY_MEMBER];
56 } lquery_level;
57 
58 #define LQL_HDRSIZE MAXALIGN( offsetof(lquery_level,variants) )
59 #define LQL_NEXT(x) ( (lquery_level*)( ((char*)(x)) + MAXALIGN(((lquery_level*)(x))->totallen) ) )
60 #define LQL_FIRST(x)	( (lquery_variant*)( ((char*)(x))+LQL_HDRSIZE ) )
61 
62 #define LQL_NOT		0x10
63 #ifdef LOWER_NODE
64 #define FLG_CANLOOKSIGN(x) ( ( (x) & ( LQL_NOT | LVAR_ANYEND | LVAR_SUBLEXEME ) ) == 0 )
65 #else
66 #define FLG_CANLOOKSIGN(x) ( ( (x) & ( LQL_NOT | LVAR_ANYEND | LVAR_SUBLEXEME | LVAR_INCASE ) ) == 0 )
67 #endif
68 #define LQL_CANLOOKSIGN(x) FLG_CANLOOKSIGN( ((lquery_level*)(x))->flag )
69 
70 typedef struct
71 {
72 	int32		vl_len_;		/* varlena header (do not touch directly!) */
73 	uint16		numlevel;
74 	uint16		firstgood;
75 	uint16		flag;
76 	char		data[FLEXIBLE_ARRAY_MEMBER];
77 } lquery;
78 
79 #define LQUERY_HDRSIZE	 MAXALIGN( offsetof(lquery, data) )
80 #define LQUERY_FIRST(x)   ( (lquery_level*)( ((char*)(x))+LQUERY_HDRSIZE ) )
81 #define LQUERY_MAX_LEVELS	PG_UINT16_MAX	/* lquery.numlevel is uint16 */
82 
83 #define LQUERY_HASNOT		0x01
84 
85 #define ISALNUM(x)	( t_isalpha(x) || t_isdigit(x)	|| ( pg_mblen(x) == 1 && t_iseq((x), '_') ) )
86 
87 /* full text query */
88 
89 /*
90  * item in polish notation with back link
91  * to left operand
92  */
93 typedef struct ITEM
94 {
95 	int16		type;
96 	int16		left;
97 	int32		val;
98 	uint8		flag;
99 	/* user-friendly value */
100 	uint8		length;
101 	uint16		distance;
102 } ITEM;
103 
104 /*
105  *Storage:
106  *		(len)(size)(array of ITEM)(array of operand in user-friendly form)
107  */
108 typedef struct
109 {
110 	int32		vl_len_;		/* varlena header (do not touch directly!) */
111 	int32		size;
112 	char		data[FLEXIBLE_ARRAY_MEMBER];
113 } ltxtquery;
114 
115 #define HDRSIZEQT		MAXALIGN(VARHDRSZ + sizeof(int32))
116 #define COMPUTESIZE(size,lenofoperand)	( HDRSIZEQT + (size) * sizeof(ITEM) + (lenofoperand) )
117 #define LTXTQUERY_TOO_BIG(size,lenofoperand) \
118 	((size) > (MaxAllocSize - HDRSIZEQT - (lenofoperand)) / sizeof(ITEM))
119 #define GETQUERY(x)  (ITEM*)( (char*)(x)+HDRSIZEQT )
120 #define GETOPERAND(x)	( (char*)GETQUERY(x) + ((ltxtquery*)x)->size * sizeof(ITEM) )
121 
122 #define ISOPERATOR(x) ( (x)=='!' || (x)=='&' || (x)=='|' || (x)=='(' || (x)==')' )
123 
124 #define END						0
125 #define ERR						1
126 #define VAL						2
127 #define OPR						3
128 #define OPEN					4
129 #define CLOSE					5
130 #define VALTRUE					6	/* for stop words */
131 #define VALFALSE				7
132 
133 
134 /* use in array iterator */
135 Datum		ltree_isparent(PG_FUNCTION_ARGS);
136 Datum		ltree_risparent(PG_FUNCTION_ARGS);
137 Datum		ltq_regex(PG_FUNCTION_ARGS);
138 Datum		ltq_rregex(PG_FUNCTION_ARGS);
139 Datum		lt_q_regex(PG_FUNCTION_ARGS);
140 Datum		lt_q_rregex(PG_FUNCTION_ARGS);
141 Datum		ltxtq_exec(PG_FUNCTION_ARGS);
142 Datum		ltxtq_rexec(PG_FUNCTION_ARGS);
143 Datum		_ltq_regex(PG_FUNCTION_ARGS);
144 Datum		_ltq_rregex(PG_FUNCTION_ARGS);
145 Datum		_lt_q_regex(PG_FUNCTION_ARGS);
146 Datum		_lt_q_rregex(PG_FUNCTION_ARGS);
147 Datum		_ltxtq_exec(PG_FUNCTION_ARGS);
148 Datum		_ltxtq_rexec(PG_FUNCTION_ARGS);
149 Datum		_ltree_isparent(PG_FUNCTION_ARGS);
150 Datum		_ltree_risparent(PG_FUNCTION_ARGS);
151 
152 /* Concatenation functions */
153 Datum		ltree_addltree(PG_FUNCTION_ARGS);
154 Datum		ltree_addtext(PG_FUNCTION_ARGS);
155 Datum		ltree_textadd(PG_FUNCTION_ARGS);
156 
157 /* Util function */
158 Datum		ltree_in(PG_FUNCTION_ARGS);
159 
160 bool ltree_execute(ITEM *curitem, void *checkval,
161 			  bool calcnot, bool (*chkcond) (void *checkval, ITEM *val));
162 
163 int			ltree_compare(const ltree *a, const ltree *b);
164 bool		inner_isparent(const ltree *c, const ltree *p);
165 bool compare_subnode(ltree_level *t, char *q, int len,
166 				int (*cmpptr) (const char *, const char *, size_t), bool anyend);
167 ltree	   *lca_inner(ltree **a, int len);
168 int			ltree_strncasecmp(const char *a, const char *b, size_t s);
169 
170 /* fmgr macros for ltree objects */
171 #define DatumGetLtreeP(X)			((ltree *) PG_DETOAST_DATUM(X))
172 #define DatumGetLtreePCopy(X)		((ltree *) PG_DETOAST_DATUM_COPY(X))
173 #define PG_GETARG_LTREE_P(n)		DatumGetLtreeP(PG_GETARG_DATUM(n))
174 #define PG_GETARG_LTREE_P_COPY(n)	DatumGetLtreePCopy(PG_GETARG_DATUM(n))
175 
176 #define DatumGetLqueryP(X)			((lquery *) PG_DETOAST_DATUM(X))
177 #define DatumGetLqueryPCopy(X)		((lquery *) PG_DETOAST_DATUM_COPY(X))
178 #define PG_GETARG_LQUERY_P(n)		DatumGetLqueryP(PG_GETARG_DATUM(n))
179 #define PG_GETARG_LQUERY_P_COPY(n)	DatumGetLqueryPCopy(PG_GETARG_DATUM(n))
180 
181 #define DatumGetLtxtqueryP(X)			((ltxtquery *) PG_DETOAST_DATUM(X))
182 #define DatumGetLtxtqueryPCopy(X)		((ltxtquery *) PG_DETOAST_DATUM_COPY(X))
183 #define PG_GETARG_LTXTQUERY_P(n)		DatumGetLtxtqueryP(PG_GETARG_DATUM(n))
184 #define PG_GETARG_LTXTQUERY_P_COPY(n)	DatumGetLtxtqueryPCopy(PG_GETARG_DATUM(n))
185 
186 /* GiST support for ltree */
187 
188 #define BITBYTE 8
189 #define SIGLENINT  2
190 #define SIGLEN	( sizeof(int32)*SIGLENINT )
191 #define SIGLENBIT (SIGLEN*BITBYTE)
192 typedef unsigned char BITVEC[SIGLEN];
193 typedef unsigned char *BITVECP;
194 
195 #define LOOPBYTE \
196 			for(i=0;i<SIGLEN;i++)
197 
198 #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) )
199 #define GETBITBYTE(x,i) ( ((unsigned char)(x)) >> i & 0x01 )
200 #define CLRBIT(x,i)   GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITBYTE ) )
201 #define SETBIT(x,i)   GETBYTE(x,i) |=  ( 0x01 << ( (i) % BITBYTE ) )
202 #define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITBYTE )) & 0x01 )
203 
204 #define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT)
205 #define HASH(sign, val) SETBIT((sign), HASHVAL(val))
206 
207 /*
208  * type of index key for ltree. Tree are combined B-Tree and R-Tree
209  * Storage:
210  *	Leaf pages
211  *		(len)(flag)(ltree)
212  *	Non-Leaf
213  *				 (len)(flag)(sign)(left_ltree)(right_ltree)
214  *		ALLTRUE: (len)(flag)(left_ltree)(right_ltree)
215  *
216  */
217 
218 typedef struct
219 {
220 	int32		vl_len_;		/* varlena header (do not touch directly!) */
221 	uint32		flag;
222 	char		data[FLEXIBLE_ARRAY_MEMBER];
223 } ltree_gist;
224 
225 #define LTG_ONENODE 0x01
226 #define LTG_ALLTRUE 0x02
227 #define LTG_NORIGHT 0x04
228 
229 #define LTG_HDRSIZE MAXALIGN(VARHDRSZ + sizeof(uint32))
230 #define LTG_SIGN(x) ( (BITVECP)( ((char*)(x))+LTG_HDRSIZE ) )
231 #define LTG_NODE(x) ( (ltree*)( ((char*)(x))+LTG_HDRSIZE ) )
232 #define LTG_ISONENODE(x) ( ((ltree_gist*)(x))->flag & LTG_ONENODE )
233 #define LTG_ISALLTRUE(x) ( ((ltree_gist*)(x))->flag & LTG_ALLTRUE )
234 #define LTG_ISNORIGHT(x) ( ((ltree_gist*)(x))->flag & LTG_NORIGHT )
235 #define LTG_LNODE(x)	( (ltree*)( ( ((char*)(x))+LTG_HDRSIZE ) + ( LTG_ISALLTRUE(x) ? 0 : SIGLEN ) ) )
236 #define LTG_RENODE(x)	( (ltree*)( ((char*)LTG_LNODE(x)) + VARSIZE(LTG_LNODE(x))) )
237 #define LTG_RNODE(x)	( LTG_ISNORIGHT(x) ? LTG_LNODE(x) : LTG_RENODE(x) )
238 
239 #define LTG_GETLNODE(x) ( LTG_ISONENODE(x) ? LTG_NODE(x) : LTG_LNODE(x) )
240 #define LTG_GETRNODE(x) ( LTG_ISONENODE(x) ? LTG_NODE(x) : LTG_RNODE(x) )
241 
242 
243 /* GiST support for ltree[] */
244 
245 #define ASIGLENINT	(7)
246 #define ASIGLEN		(sizeof(int32)*ASIGLENINT)
247 #define ASIGLENBIT (ASIGLEN*BITBYTE)
248 typedef unsigned char ABITVEC[ASIGLEN];
249 
250 #define ALOOPBYTE \
251 			for(i=0;i<ASIGLEN;i++)
252 
253 #define AHASHVAL(val) (((unsigned int)(val)) % ASIGLENBIT)
254 #define AHASH(sign, val) SETBIT((sign), AHASHVAL(val))
255 
256 /* type of key is the same to ltree_gist */
257 
258 #endif
259