Header And Logo

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

hstore.h

Go to the documentation of this file.
00001 /*
00002  * contrib/hstore/hstore.h
00003  */
00004 #ifndef __HSTORE_H__
00005 #define __HSTORE_H__
00006 
00007 #include "fmgr.h"
00008 #include "utils/array.h"
00009 
00010 
00011 /*
00012  * HEntry: there is one of these for each key _and_ value in an hstore
00013  *
00014  * the position offset points to the _end_ so that we can get the length
00015  * by subtraction from the previous entry.  the ISFIRST flag lets us tell
00016  * whether there is a previous entry.
00017  */
00018 typedef struct
00019 {
00020     uint32      entry;
00021 } HEntry;
00022 
00023 #define HENTRY_ISFIRST 0x80000000
00024 #define HENTRY_ISNULL  0x40000000
00025 #define HENTRY_POSMASK 0x3FFFFFFF
00026 
00027 /* note possible multiple evaluations, also access to prior array element */
00028 #define HSE_ISFIRST(he_) (((he_).entry & HENTRY_ISFIRST) != 0)
00029 #define HSE_ISNULL(he_) (((he_).entry & HENTRY_ISNULL) != 0)
00030 #define HSE_ENDPOS(he_) ((he_).entry & HENTRY_POSMASK)
00031 #define HSE_OFF(he_) (HSE_ISFIRST(he_) ? 0 : HSE_ENDPOS((&(he_))[-1]))
00032 #define HSE_LEN(he_) (HSE_ISFIRST(he_)  \
00033                       ? HSE_ENDPOS(he_) \
00034                       : HSE_ENDPOS(he_) - HSE_ENDPOS((&(he_))[-1]))
00035 
00036 /*
00037  * determined by the size of "endpos" (ie HENTRY_POSMASK), though this is a
00038  * bit academic since currently varlenas (and hence both the input and the
00039  * whole hstore) have the same limit
00040  */
00041 #define HSTORE_MAX_KEY_LEN 0x3FFFFFFF
00042 #define HSTORE_MAX_VALUE_LEN 0x3FFFFFFF
00043 
00044 typedef struct
00045 {
00046     int32       vl_len_;        /* varlena header (do not touch directly!) */
00047     uint32      size_;          /* flags and number of items in hstore */
00048     /* array of HEntry follows */
00049 } HStore;
00050 
00051 /*
00052  * it's not possible to get more than 2^28 items into an hstore,
00053  * so we reserve the top few bits of the size field. See hstore_compat.c
00054  * for one reason why.  Some bits are left for future use here.
00055  */
00056 #define HS_FLAG_NEWVERSION 0x80000000
00057 
00058 #define HS_COUNT(hsp_) ((hsp_)->size_ & 0x0FFFFFFF)
00059 #define HS_SETCOUNT(hsp_,c_) ((hsp_)->size_ = (c_) | HS_FLAG_NEWVERSION)
00060 
00061 
00062 #define HSHRDSIZE   (sizeof(HStore))
00063 #define CALCDATASIZE(x, lenstr) ( (x) * 2 * sizeof(HEntry) + HSHRDSIZE + (lenstr) )
00064 
00065 /* note multiple evaluations of x */
00066 #define ARRPTR(x)       ( (HEntry*) ( (HStore*)(x) + 1 ) )
00067 #define STRPTR(x)       ( (char*)(ARRPTR(x) + HS_COUNT((HStore*)(x)) * 2) )
00068 
00069 /* note multiple/non evaluations */
00070 #define HS_KEY(arr_,str_,i_) ((str_) + HSE_OFF((arr_)[2*(i_)]))
00071 #define HS_VAL(arr_,str_,i_) ((str_) + HSE_OFF((arr_)[2*(i_)+1]))
00072 #define HS_KEYLEN(arr_,i_) (HSE_LEN((arr_)[2*(i_)]))
00073 #define HS_VALLEN(arr_,i_) (HSE_LEN((arr_)[2*(i_)+1]))
00074 #define HS_VALISNULL(arr_,i_) (HSE_ISNULL((arr_)[2*(i_)+1]))
00075 
00076 /*
00077  * currently, these following macros are the _only_ places that rely
00078  * on internal knowledge of HEntry. Everything else should be using
00079  * the above macros. Exception: the in-place upgrade in hstore_compat.c
00080  * messes with entries directly.
00081  */
00082 
00083 /*
00084  * copy one key/value pair (which must be contiguous starting at
00085  * sptr_) into an under-construction hstore; dent_ is an HEntry*,
00086  * dbuf_ is the destination's string buffer, dptr_ is the current
00087  * position in the destination. lots of modification and multiple
00088  * evaluation here.
00089  */
00090 #define HS_COPYITEM(dent_,dbuf_,dptr_,sptr_,klen_,vlen_,vnull_)         \
00091     do {                                                                \
00092         memcpy((dptr_), (sptr_), (klen_)+(vlen_));                      \
00093         (dptr_) += (klen_)+(vlen_);                                     \
00094         (dent_)++->entry = ((dptr_) - (dbuf_) - (vlen_)) & HENTRY_POSMASK; \
00095         (dent_)++->entry = ((((dptr_) - (dbuf_)) & HENTRY_POSMASK)      \
00096                              | ((vnull_) ? HENTRY_ISNULL : 0));         \
00097     } while(0)
00098 
00099 /*
00100  * add one key/item pair, from a Pairs structure, into an
00101  * under-construction hstore
00102  */
00103 #define HS_ADDITEM(dent_,dbuf_,dptr_,pair_)                             \
00104     do {                                                                \
00105         memcpy((dptr_), (pair_).key, (pair_).keylen);                   \
00106         (dptr_) += (pair_).keylen;                                      \
00107         (dent_)++->entry = ((dptr_) - (dbuf_)) & HENTRY_POSMASK;        \
00108         if ((pair_).isnull)                                             \
00109             (dent_)++->entry = ((((dptr_) - (dbuf_)) & HENTRY_POSMASK)  \
00110                                  | HENTRY_ISNULL);                      \
00111         else                                                            \
00112         {                                                               \
00113             memcpy((dptr_), (pair_).val, (pair_).vallen);               \
00114             (dptr_) += (pair_).vallen;                                  \
00115             (dent_)++->entry = ((dptr_) - (dbuf_)) & HENTRY_POSMASK;    \
00116         }                                                               \
00117     } while (0)
00118 
00119 /* finalize a newly-constructed hstore */
00120 #define HS_FINALIZE(hsp_,count_,buf_,ptr_)                          \
00121     do {                                                            \
00122         int buflen = (ptr_) - (buf_);                               \
00123         if ((count_))                                               \
00124             ARRPTR(hsp_)[0].entry |= HENTRY_ISFIRST;                \
00125         if ((count_) != HS_COUNT((hsp_)))                           \
00126         {                                                           \
00127             HS_SETCOUNT((hsp_),(count_));                           \
00128             memmove(STRPTR(hsp_), (buf_), buflen);                  \
00129         }                                                           \
00130         SET_VARSIZE((hsp_), CALCDATASIZE((count_), buflen));        \
00131     } while (0)
00132 
00133 /* ensure the varlena size of an existing hstore is correct */
00134 #define HS_FIXSIZE(hsp_,count_)                                         \
00135     do {                                                                \
00136         int bl = (count_) ? HSE_ENDPOS(ARRPTR(hsp_)[2*(count_)-1]) : 0; \
00137         SET_VARSIZE((hsp_), CALCDATASIZE((count_),bl));                 \
00138     } while (0)
00139 
00140 /* DatumGetHStoreP includes support for reading old-format hstore values */
00141 extern HStore *hstoreUpgrade(Datum orig);
00142 
00143 #define DatumGetHStoreP(d) hstoreUpgrade(d)
00144 
00145 #define PG_GETARG_HS(x) DatumGetHStoreP(PG_GETARG_DATUM(x))
00146 
00147 
00148 /*
00149  * Pairs is a "decompressed" representation of one key/value pair.
00150  * The two strings are not necessarily null-terminated.
00151  */
00152 typedef struct
00153 {
00154     char       *key;
00155     char       *val;
00156     size_t      keylen;
00157     size_t      vallen;
00158     bool        isnull;         /* value is null? */
00159     bool        needfree;       /* need to pfree the value? */
00160 } Pairs;
00161 
00162 extern int  hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen);
00163 extern HStore *hstorePairs(Pairs *pairs, int32 pcount, int32 buflen);
00164 
00165 extern size_t hstoreCheckKeyLen(size_t len);
00166 extern size_t hstoreCheckValLen(size_t len);
00167 
00168 extern int  hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen);
00169 extern Pairs *hstoreArrayToPairs(ArrayType *a, int *npairs);
00170 
00171 #define HStoreContainsStrategyNumber    7
00172 #define HStoreExistsStrategyNumber      9
00173 #define HStoreExistsAnyStrategyNumber   10
00174 #define HStoreExistsAllStrategyNumber   11
00175 #define HStoreOldContainsStrategyNumber 13      /* backwards compatibility */
00176 
00177 /*
00178  * defining HSTORE_POLLUTE_NAMESPACE=0 will prevent use of old function names;
00179  * for now, we default to on for the benefit of people restoring old dumps
00180  */
00181 #ifndef HSTORE_POLLUTE_NAMESPACE
00182 #define HSTORE_POLLUTE_NAMESPACE 1
00183 #endif
00184 
00185 #if HSTORE_POLLUTE_NAMESPACE
00186 #define HSTORE_POLLUTE(newname_,oldname_) \
00187     PG_FUNCTION_INFO_V1(oldname_);        \
00188     Datum oldname_(PG_FUNCTION_ARGS);     \
00189     Datum newname_(PG_FUNCTION_ARGS);     \
00190     Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \
00191     extern int no_such_variable
00192 #else
00193 #define HSTORE_POLLUTE(newname_,oldname_) \
00194     extern int no_such_variable
00195 #endif
00196 
00197 #endif   /* __HSTORE_H__ */