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