2 * contrib/hstore/hstore.h
8 #include "utils/array.h"
12 * HEntry: there is one of these for each key _and_ value in an hstore
14 * the position offset points to the _end_ so that we can get the length
15 * by subtraction from the previous entry. the ISFIRST flag lets us tell
16 * whether there is a previous entry.
23 #define HENTRY_ISFIRST 0x80000000
24 #define HENTRY_ISNULL 0x40000000
25 #define HENTRY_POSMASK 0x3FFFFFFF
27 /* note possible multiple evaluations, also access to prior array element */
28 #define HSE_ISFIRST(he_) (((he_).entry & HENTRY_ISFIRST) != 0)
29 #define HSE_ISNULL(he_) (((he_).entry & HENTRY_ISNULL) != 0)
30 #define HSE_ENDPOS(he_) ((he_).entry & HENTRY_POSMASK)
31 #define HSE_OFF(he_) (HSE_ISFIRST(he_) ? 0 : HSE_ENDPOS((&(he_))[-1]))
32 #define HSE_LEN(he_) (HSE_ISFIRST(he_) \
34 : HSE_ENDPOS(he_) - HSE_ENDPOS((&(he_))[-1]))
37 * determined by the size of "endpos" (ie HENTRY_POSMASK), though this is a
38 * bit academic since currently varlenas (and hence both the input and the
39 * whole hstore) have the same limit
41 #define HSTORE_MAX_KEY_LEN 0x3FFFFFFF
42 #define HSTORE_MAX_VALUE_LEN 0x3FFFFFFF
46 int32 vl_len_
; /* varlena header (do not touch directly!) */
47 uint32 size_
; /* flags and number of items in hstore */
48 /* array of HEntry follows */
52 * It's not possible to get more than 2^28 items into an hstore, so we reserve
53 * the top few bits of the size field. See hstore_compat.c for one reason
54 * why. Some bits are left for future use here. MaxAllocSize makes the
55 * practical count limit slightly more than 2^28 / 3, or INT_MAX / 24, the
56 * limit for an hstore full of 4-byte keys and null values. Therefore, we
57 * don't explicitly check the format-imposed limit.
59 #define HS_FLAG_NEWVERSION 0x80000000
61 #define HS_COUNT(hsp_) ((hsp_)->size_ & 0x0FFFFFFF)
62 #define HS_SETCOUNT(hsp_,c_) ((hsp_)->size_ = (c_) | HS_FLAG_NEWVERSION)
66 * "x" comes from an existing HS_COUNT() (as discussed, <= INT_MAX/24) or a
67 * Pairs array length (due to MaxAllocSize, <= INT_MAX/40). "lenstr" is no
68 * more than INT_MAX, that extreme case arising in hstore_from_arrays().
69 * Therefore, this calculation is limited to about INT_MAX / 5 + INT_MAX.
71 #define HSHRDSIZE (sizeof(HStore))
72 #define CALCDATASIZE(x, lenstr) ( (x) * 2 * sizeof(HEntry) + HSHRDSIZE + (lenstr) )
74 /* note multiple evaluations of x */
75 #define ARRPTR(x) ( (HEntry*) ( (HStore*)(x) + 1 ) )
76 #define STRPTR(x) ( (char*)(ARRPTR(x) + HS_COUNT((HStore*)(x)) * 2) )
78 /* note multiple/non evaluations */
79 #define HSTORE_KEY(arr_,str_,i_) ((str_) + HSE_OFF((arr_)[2*(i_)]))
80 #define HSTORE_VAL(arr_,str_,i_) ((str_) + HSE_OFF((arr_)[2*(i_)+1]))
81 #define HSTORE_KEYLEN(arr_,i_) (HSE_LEN((arr_)[2*(i_)]))
82 #define HSTORE_VALLEN(arr_,i_) (HSE_LEN((arr_)[2*(i_)+1]))
83 #define HSTORE_VALISNULL(arr_,i_) (HSE_ISNULL((arr_)[2*(i_)+1]))
86 * currently, these following macros are the _only_ places that rely
87 * on internal knowledge of HEntry. Everything else should be using
88 * the above macros. Exception: the in-place upgrade in hstore_compat.c
89 * messes with entries directly.
93 * copy one key/value pair (which must be contiguous starting at
94 * sptr_) into an under-construction hstore; dent_ is an HEntry*,
95 * dbuf_ is the destination's string buffer, dptr_ is the current
96 * position in the destination. lots of modification and multiple
99 #define HS_COPYITEM(dent_,dbuf_,dptr_,sptr_,klen_,vlen_,vnull_) \
101 memcpy((dptr_), (sptr_), (klen_)+(vlen_)); \
102 (dptr_) += (klen_)+(vlen_); \
103 (dent_)++->entry = ((dptr_) - (dbuf_) - (vlen_)) & HENTRY_POSMASK; \
104 (dent_)++->entry = ((((dptr_) - (dbuf_)) & HENTRY_POSMASK) \
105 | ((vnull_) ? HENTRY_ISNULL : 0)); \
109 * add one key/item pair, from a Pairs structure, into an
110 * under-construction hstore
112 #define HS_ADDITEM(dent_,dbuf_,dptr_,pair_) \
114 memcpy((dptr_), (pair_).key, (pair_).keylen); \
115 (dptr_) += (pair_).keylen; \
116 (dent_)++->entry = ((dptr_) - (dbuf_)) & HENTRY_POSMASK; \
117 if ((pair_).isnull) \
118 (dent_)++->entry = ((((dptr_) - (dbuf_)) & HENTRY_POSMASK) \
122 memcpy((dptr_), (pair_).val, (pair_).vallen); \
123 (dptr_) += (pair_).vallen; \
124 (dent_)++->entry = ((dptr_) - (dbuf_)) & HENTRY_POSMASK; \
128 /* finalize a newly-constructed hstore */
129 #define HS_FINALIZE(hsp_,count_,buf_,ptr_) \
131 int _buflen = (ptr_) - (buf_); \
133 ARRPTR(hsp_)[0].entry |= HENTRY_ISFIRST; \
134 if ((count_) != HS_COUNT((hsp_))) \
136 HS_SETCOUNT((hsp_),(count_)); \
137 memmove(STRPTR(hsp_), (buf_), _buflen); \
139 SET_VARSIZE((hsp_), CALCDATASIZE((count_), _buflen)); \
142 /* ensure the varlena size of an existing hstore is correct */
143 #define HS_FIXSIZE(hsp_,count_) \
145 int bl = (count_) ? HSE_ENDPOS(ARRPTR(hsp_)[2*(count_)-1]) : 0; \
146 SET_VARSIZE((hsp_), CALCDATASIZE((count_),bl)); \
149 /* DatumGetHStoreP includes support for reading old-format hstore values */
150 extern PGDLLEXPORT HStore
*hstoreUpgrade(Datum orig
);
152 #define DatumGetHStoreP(d) hstoreUpgrade(d)
154 #define PG_GETARG_HSTORE_P(x) DatumGetHStoreP(PG_GETARG_DATUM(x))
158 * Pairs is a "decompressed" representation of one key/value pair.
159 * The two strings are not necessarily null-terminated.
167 bool isnull
; /* value is null? */
168 bool needfree
; /* need to pfree the value? */
171 extern PGDLLEXPORT
int hstoreUniquePairs(Pairs
*a
, int32 l
, int32
*buflen
);
172 extern PGDLLEXPORT HStore
*hstorePairs(Pairs
*pairs
, int32 pcount
, int32 buflen
);
174 extern PGDLLEXPORT
size_t hstoreCheckKeyLen(size_t len
);
175 extern PGDLLEXPORT
size_t hstoreCheckValLen(size_t len
);
177 extern PGDLLEXPORT
int hstoreFindKey(HStore
*hs
, int *lowbound
, char *key
, int keylen
);
178 extern PGDLLEXPORT Pairs
*hstoreArrayToPairs(ArrayType
*a
, int *npairs
);
180 #define HStoreContainsStrategyNumber 7
181 #define HStoreExistsStrategyNumber 9
182 #define HStoreExistsAnyStrategyNumber 10
183 #define HStoreExistsAllStrategyNumber 11
184 #define HStoreOldContainsStrategyNumber 13 /* backwards compatibility */
187 * defining HSTORE_POLLUTE_NAMESPACE=0 will prevent use of old function names;
188 * for now, we default to on for the benefit of people restoring old dumps
190 #ifndef HSTORE_POLLUTE_NAMESPACE
191 #define HSTORE_POLLUTE_NAMESPACE 1
194 #if HSTORE_POLLUTE_NAMESPACE
195 #define HSTORE_POLLUTE(newname_,oldname_) \
196 PG_FUNCTION_INFO_V1(oldname_); \
197 extern PGDLLEXPORT Datum newname_(PG_FUNCTION_ARGS); \
198 Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \
199 extern int no_such_variable
201 #define HSTORE_POLLUTE(newname_,oldname_) \
202 extern int no_such_variable
205 #endif /* __HSTORE_H__ */