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