Header And Logo

PostgreSQL
| The world's most advanced open source database.

ltree.h

Go to the documentation of this file.
00001 /* contrib/ltree/ltree.h */
00002 
00003 #ifndef __LTREE_H__
00004 #define __LTREE_H__
00005 
00006 #include "fmgr.h"
00007 #include "tsearch/ts_locale.h"
00008 
00009 typedef struct
00010 {
00011     uint16      len;
00012     char        name[1];
00013 } ltree_level;
00014 
00015 #define LEVEL_HDRSIZE   (offsetof(ltree_level,name))
00016 #define LEVEL_NEXT(x)   ( (ltree_level*)( ((char*)(x)) + MAXALIGN(((ltree_level*)(x))->len + LEVEL_HDRSIZE) ) )
00017 
00018 typedef struct
00019 {
00020     int32       vl_len_;        /* varlena header (do not touch directly!) */
00021     uint16      numlevel;
00022     char        data[1];
00023 } ltree;
00024 
00025 #define LTREE_HDRSIZE   MAXALIGN( offsetof(ltree, data) )
00026 #define LTREE_FIRST(x)  ( (ltree_level*)( ((char*)(x))+LTREE_HDRSIZE ) )
00027 
00028 
00029 /* lquery */
00030 
00031 typedef struct
00032 {
00033     int32       val;
00034     uint16      len;
00035     uint8       flag;
00036     char        name[1];
00037 } lquery_variant;
00038 
00039 #define LVAR_HDRSIZE   MAXALIGN(offsetof(lquery_variant, name))
00040 #define LVAR_NEXT(x)    ( (lquery_variant*)( ((char*)(x)) + MAXALIGN(((lquery_variant*)(x))->len) + LVAR_HDRSIZE ) )
00041 
00042 #define LVAR_ANYEND 0x01
00043 #define LVAR_INCASE 0x02
00044 #define LVAR_SUBLEXEME  0x04
00045 
00046 typedef struct
00047 {
00048     uint16      totallen;
00049     uint16      flag;
00050     uint16      numvar;
00051     uint16      low;
00052     uint16      high;
00053     char        variants[1];
00054 } lquery_level;
00055 
00056 #define LQL_HDRSIZE MAXALIGN( offsetof(lquery_level,variants) )
00057 #define LQL_NEXT(x) ( (lquery_level*)( ((char*)(x)) + MAXALIGN(((lquery_level*)(x))->totallen) ) )
00058 #define LQL_FIRST(x)    ( (lquery_variant*)( ((char*)(x))+LQL_HDRSIZE ) )
00059 
00060 #define LQL_NOT     0x10
00061 #ifdef LOWER_NODE
00062 #define FLG_CANLOOKSIGN(x) ( ( (x) & ( LQL_NOT | LVAR_ANYEND | LVAR_SUBLEXEME ) ) == 0 )
00063 #else
00064 #define FLG_CANLOOKSIGN(x) ( ( (x) & ( LQL_NOT | LVAR_ANYEND | LVAR_SUBLEXEME | LVAR_INCASE ) ) == 0 )
00065 #endif
00066 #define LQL_CANLOOKSIGN(x) FLG_CANLOOKSIGN( ((lquery_level*)(x))->flag )
00067 
00068 typedef struct
00069 {
00070     int32       vl_len_;        /* varlena header (do not touch directly!) */
00071     uint16      numlevel;
00072     uint16      firstgood;
00073     uint16      flag;
00074     char        data[1];
00075 } lquery;
00076 
00077 #define LQUERY_HDRSIZE   MAXALIGN( offsetof(lquery, data) )
00078 #define LQUERY_FIRST(x)   ( (lquery_level*)( ((char*)(x))+LQUERY_HDRSIZE ) )
00079 
00080 #define LQUERY_HASNOT       0x01
00081 
00082 #define ISALNUM(x)  ( t_isalpha(x) || t_isdigit(x)  || ( pg_mblen(x) == 1 && t_iseq((x), '_') ) )
00083 
00084 /* full text query */
00085 
00086 /*
00087  * item in polish notation with back link
00088  * to left operand
00089  */
00090 typedef struct ITEM
00091 {
00092     int16       type;
00093     int16       left;
00094     int32       val;
00095     uint8       flag;
00096     /* user-friendly value */
00097     uint8       length;
00098     uint16      distance;
00099 } ITEM;
00100 
00101 /*
00102  *Storage:
00103  *      (len)(size)(array of ITEM)(array of operand in user-friendly form)
00104  */
00105 typedef struct
00106 {
00107     int32       vl_len_;        /* varlena header (do not touch directly!) */
00108     int32       size;
00109     char        data[1];
00110 } ltxtquery;
00111 
00112 #define HDRSIZEQT       MAXALIGN(VARHDRSZ + sizeof(int32))
00113 #define COMPUTESIZE(size,lenofoperand)  ( HDRSIZEQT + (size) * sizeof(ITEM) + (lenofoperand) )
00114 #define GETQUERY(x)  (ITEM*)( (char*)(x)+HDRSIZEQT )
00115 #define GETOPERAND(x)   ( (char*)GETQUERY(x) + ((ltxtquery*)x)->size * sizeof(ITEM) )
00116 
00117 #define ISOPERATOR(x) ( (x)=='!' || (x)=='&' || (x)=='|' || (x)=='(' || (x)==')' )
00118 
00119 #define END                     0
00120 #define ERR                     1
00121 #define VAL                     2
00122 #define OPR                     3
00123 #define OPEN                    4
00124 #define CLOSE                   5
00125 #define VALTRUE                 6       /* for stop words */
00126 #define VALFALSE                7
00127 
00128 
00129 /* use in array iterator */
00130 Datum       ltree_isparent(PG_FUNCTION_ARGS);
00131 Datum       ltree_risparent(PG_FUNCTION_ARGS);
00132 Datum       ltq_regex(PG_FUNCTION_ARGS);
00133 Datum       ltq_rregex(PG_FUNCTION_ARGS);
00134 Datum       lt_q_regex(PG_FUNCTION_ARGS);
00135 Datum       lt_q_rregex(PG_FUNCTION_ARGS);
00136 Datum       ltxtq_exec(PG_FUNCTION_ARGS);
00137 Datum       ltxtq_rexec(PG_FUNCTION_ARGS);
00138 Datum       _ltq_regex(PG_FUNCTION_ARGS);
00139 Datum       _ltq_rregex(PG_FUNCTION_ARGS);
00140 Datum       _lt_q_regex(PG_FUNCTION_ARGS);
00141 Datum       _lt_q_rregex(PG_FUNCTION_ARGS);
00142 Datum       _ltxtq_exec(PG_FUNCTION_ARGS);
00143 Datum       _ltxtq_rexec(PG_FUNCTION_ARGS);
00144 Datum       _ltree_isparent(PG_FUNCTION_ARGS);
00145 Datum       _ltree_risparent(PG_FUNCTION_ARGS);
00146 
00147 /* Concatenation functions */
00148 Datum       ltree_addltree(PG_FUNCTION_ARGS);
00149 Datum       ltree_addtext(PG_FUNCTION_ARGS);
00150 Datum       ltree_textadd(PG_FUNCTION_ARGS);
00151 
00152 /* Util function */
00153 Datum       ltree_in(PG_FUNCTION_ARGS);
00154 
00155 bool ltree_execute(ITEM *curitem, void *checkval,
00156               bool calcnot, bool (*chkcond) (void *checkval, ITEM *val));
00157 
00158 int         ltree_compare(const ltree *a, const ltree *b);
00159 bool        inner_isparent(const ltree *c, const ltree *p);
00160 bool compare_subnode(ltree_level *t, char *q, int len,
00161             int (*cmpptr) (const char *, const char *, size_t), bool anyend);
00162 ltree      *lca_inner(ltree **a, int len);
00163 int         ltree_strncasecmp(const char *a, const char *b, size_t s);
00164 
00165 #define PG_GETARG_LTREE(x)  ((ltree*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(x))))
00166 #define PG_GETARG_LTREE_COPY(x) ((ltree*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(x))))
00167 #define PG_GETARG_LQUERY(x) ((lquery*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(x))))
00168 #define PG_GETARG_LQUERY_COPY(x) ((lquery*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(x))))
00169 #define PG_GETARG_LTXTQUERY(x) ((ltxtquery*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(x))))
00170 #define PG_GETARG_LTXTQUERY_COPY(x) ((ltxtquery*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(x))))
00171 
00172 /* GiST support for ltree */
00173 
00174 #define BITBYTE 8
00175 #define SIGLENINT  2
00176 #define SIGLEN  ( sizeof(int32)*SIGLENINT )
00177 #define SIGLENBIT (SIGLEN*BITBYTE)
00178 typedef unsigned char BITVEC[SIGLEN];
00179 typedef unsigned char *BITVECP;
00180 
00181 #define LOOPBYTE \
00182             for(i=0;i<SIGLEN;i++)
00183 
00184 #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) )
00185 #define GETBITBYTE(x,i) ( ((unsigned char)(x)) >> i & 0x01 )
00186 #define CLRBIT(x,i)   GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITBYTE ) )
00187 #define SETBIT(x,i)   GETBYTE(x,i) |=  ( 0x01 << ( (i) % BITBYTE ) )
00188 #define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITBYTE )) & 0x01 )
00189 
00190 #define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT)
00191 #define HASH(sign, val) SETBIT((sign), HASHVAL(val))
00192 
00193 /*
00194  * type of index key for ltree. Tree are combined B-Tree and R-Tree
00195  * Storage:
00196  *  Leaf pages
00197  *      (len)(flag)(ltree)
00198  *  Non-Leaf
00199  *               (len)(flag)(sign)(left_ltree)(right_ltree)
00200  *      ALLTRUE: (len)(flag)(left_ltree)(right_ltree)
00201  *
00202  */
00203 
00204 typedef struct
00205 {
00206     int32       vl_len_;        /* varlena header (do not touch directly!) */
00207     uint32      flag;
00208     char        data[1];
00209 } ltree_gist;
00210 
00211 #define LTG_ONENODE 0x01
00212 #define LTG_ALLTRUE 0x02
00213 #define LTG_NORIGHT 0x04
00214 
00215 #define LTG_HDRSIZE MAXALIGN(VARHDRSZ + sizeof(uint32))
00216 #define LTG_SIGN(x) ( (BITVECP)( ((char*)(x))+LTG_HDRSIZE ) )
00217 #define LTG_NODE(x) ( (ltree*)( ((char*)(x))+LTG_HDRSIZE ) )
00218 #define LTG_ISONENODE(x) ( ((ltree_gist*)(x))->flag & LTG_ONENODE )
00219 #define LTG_ISALLTRUE(x) ( ((ltree_gist*)(x))->flag & LTG_ALLTRUE )
00220 #define LTG_ISNORIGHT(x) ( ((ltree_gist*)(x))->flag & LTG_NORIGHT )
00221 #define LTG_LNODE(x)    ( (ltree*)( ( ((char*)(x))+LTG_HDRSIZE ) + ( LTG_ISALLTRUE(x) ? 0 : SIGLEN ) ) )
00222 #define LTG_RENODE(x)   ( (ltree*)( ((char*)LTG_LNODE(x)) + VARSIZE(LTG_LNODE(x))) )
00223 #define LTG_RNODE(x)    ( LTG_ISNORIGHT(x) ? LTG_LNODE(x) : LTG_RENODE(x) )
00224 
00225 #define LTG_GETLNODE(x) ( LTG_ISONENODE(x) ? LTG_NODE(x) : LTG_LNODE(x) )
00226 #define LTG_GETRNODE(x) ( LTG_ISONENODE(x) ? LTG_NODE(x) : LTG_RNODE(x) )
00227 
00228 
00229 /* GiST support for ltree[] */
00230 
00231 #define ASIGLENINT  (7)
00232 #define ASIGLEN     (sizeof(int32)*ASIGLENINT)
00233 #define ASIGLENBIT (ASIGLEN*BITBYTE)
00234 typedef unsigned char ABITVEC[ASIGLEN];
00235 
00236 #define ALOOPBYTE \
00237             for(i=0;i<ASIGLEN;i++)
00238 
00239 #define AHASHVAL(val) (((unsigned int)(val)) % ASIGLENBIT)
00240 #define AHASH(sign, val) SETBIT((sign), AHASHVAL(val))
00241 
00242 /* type of key is the same to ltree_gist */
00243 
00244 #endif