00001
00002
00003
00004 #ifndef __HSTORE_H__
00005 #define __HSTORE_H__
00006
00007 #include "fmgr.h"
00008 #include "utils/array.h"
00009
00010
00011
00012
00013
00014
00015
00016
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
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
00038
00039
00040
00041 #define HSTORE_MAX_KEY_LEN 0x3FFFFFFF
00042 #define HSTORE_MAX_VALUE_LEN 0x3FFFFFFF
00043
00044 typedef struct
00045 {
00046 int32 vl_len_;
00047 uint32 size_;
00048
00049 } HStore;
00050
00051
00052
00053
00054
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
00066 #define ARRPTR(x) ( (HEntry*) ( (HStore*)(x) + 1 ) )
00067 #define STRPTR(x) ( (char*)(ARRPTR(x) + HS_COUNT((HStore*)(x)) * 2) )
00068
00069
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
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
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
00101
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
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
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
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
00150
00151
00152 typedef struct
00153 {
00154 char *key;
00155 char *val;
00156 size_t keylen;
00157 size_t vallen;
00158 bool isnull;
00159 bool needfree;
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
00176
00177
00178
00179
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