2 * contrib/hstore/hstore.h
8 #include "lib/stringinfo.h"
9 #include "utils/array.h"
10 #include "utils/numeric.h"
13 * HEntry: there is one of these for each key _and_ value in an hstore
15 * the position offset points to the _end_ so that we can get the length
16 * by subtraction from the previous entry. the ISFIRST flag lets us tell
17 * whether there is a previous entry.
24 #define HENTRY_ISFIRST 0x80000000
25 #define HENTRY_ISSTRING (0x00000000) /* keep binary compatibility */
26 #define HENTRY_ISNUMERIC (0x10000000)
27 #define HENTRY_ISNEST (0x20000000)
28 #define HENTRY_ISNULL (0x40000000) /* keep binary compatibility */
29 #define HENTRY_ISBOOL (0x10000000 | 0x20000000)
30 #define HENTRY_ISFALSE HENTRY_ISBOOL
31 #define HENTRY_ISTRUE (0x10000000 | 0x20000000 | 0x40000000)
33 /* HENTRY_ISHASH, HENTRY_ISARRAY and HENTRY_ISSCALAR is only used in send/recv */
34 #define HENTRY_ISHASH (0x20000000)
35 #define HENTRY_ISARRAY (0x20000000 | 0x40000000)
36 #define HENTRY_ISSCALAR (0x10000000 | 0x40000000)
38 #define HENTRY_POSMASK 0x0FFFFFFF
39 #define HENTRY_TYPEMASK (~(HENTRY_POSMASK | HENTRY_ISFIRST))
41 /* note possible multiple evaluations, also access to prior array element */
42 #define HSE_ISFIRST(he_) (((he_).entry & HENTRY_ISFIRST) != 0)
43 #define HSE_ISSTRING(he_) (((he_).entry & HENTRY_TYPEMASK) == \
45 #define HSE_ISNUMERIC(he_) (((he_).entry & HENTRY_TYPEMASK) == \
47 #define HSE_ISNEST(he_) (((he_).entry & HENTRY_TYPEMASK) == \
49 #define HSE_ISNULL(he_) (((he_).entry & HENTRY_TYPEMASK) == \
51 #define HSE_ISBOOL(he_) (((he_).entry & HENTRY_ISBOOL) == \
53 #define HSE_ISBOOL_TRUE(he_) (((he_).entry & HENTRY_TYPEMASK) == \
55 #define HSE_ISBOOL_FALSE(he_) (HSE_ISBOOL(he_) && !HSE_ISBOOL_TRUE(he_))
57 #define HSE_ENDPOS(he_) ((he_).entry & HENTRY_POSMASK)
58 #define HSE_OFF(he_) (HSE_ISFIRST(he_) ? 0 : HSE_ENDPOS((&(he_))[-1]))
59 #define HSE_LEN(he_) (HSE_ISFIRST(he_) \
61 : HSE_ENDPOS(he_) - HSE_ENDPOS((&(he_))[-1]))
64 * determined by the size of "endpos" (ie HENTRY_POSMASK)
66 #define HSTORE_MAX_KEY_LEN HENTRY_POSMASK
67 #define HSTORE_MAX_VALUE_LEN HENTRY_POSMASK
71 int32 vl_len_; /* varlena header (do not touch directly!) */
72 /* header of hash or array hstore type */
73 /* array of HEntry follows */
77 * It's not possible to get more than 2^28 items into an hstore, so we reserve
78 * the top few bits of the size field. See hstore_compat.c for one reason
79 * why. Some bits are left for future use here. MaxAllocSize makes the
80 * practical count limit slightly more than 2^28 / 3, or INT_MAX / 24, the
81 * limit for an hstore full of 4-byte keys and null values. Therefore, we
82 * don't explicitly check the format-imposed limit.
84 #define HS_FLAG_NEWVERSION 0x80000000
85 #define HS_FLAG_ARRAY 0x40000000
86 #define HS_FLAG_HSTORE 0x20000000
87 #define HS_FLAG_SCALAR 0x10000000
89 #define HS_COUNT_MASK 0x0FFFFFFF
91 #define HS_ISEMPTY(hsp_) (VARSIZE(hsp_) <= VARHDRSZ)
92 #define HS_ROOT_COUNT(hsp_) (HS_ISEMPTY(hsp_) ? 0 : \
93 ( *(uint32*)VARDATA(hsp_) & HS_COUNT_MASK))
94 #define HS_ROOT_IS_HASH(hsp_) (HS_ISEMPTY(hsp_) ? 0 : \
95 ( *(uint32*)VARDATA(hsp_) & HS_FLAG_HSTORE))
96 #define HS_ROOT_IS_ARRAY(hsp_) (HS_ISEMPTY(hsp_) ? 0 : \
97 ( *(uint32*)VARDATA(hsp_) & HS_FLAG_ARRAY))
98 #define HS_ROOT_IS_SCALAR(hsp_) (HS_ISEMPTY(hsp_) ? 0 : \
99 ( *(uint32*)VARDATA(hsp_) & HS_FLAG_SCALAR))
101 /* DatumGetHStoreP includes support for reading old-format hstore values */
102 extern HStore *hstoreUpgrade(Datum orig);
104 #define DatumGetHStoreP(d) hstoreUpgrade(d)
106 #define PG_GETARG_HS(x) DatumGetHStoreP(PG_GETARG_DATUM(x))
108 typedef struct HStorePair HStorePair;
109 typedef struct HStoreValue HStoreValue;
119 hsvBinary /* binary form of hsvArray/hsvHash */
122 uint32 size; /* estimation size of node (including subnodes) */
129 char *val; /* could be not null-terminated */
136 * scalar actually shares representation with array
157 uint32 order; /* to keep order of pairs with equal key */
161 extern HStoreValue* parseHStore(const char *str, int len, bool json);
164 * hstore support functios
167 #define WHS_KEY (0x001)
168 #define WHS_VALUE (0x002)
169 #define WHS_ELEM (0x004)
170 #define WHS_BEGIN_ARRAY (0x008)
171 #define WHS_END_ARRAY (0x010)
172 #define WHS_BEGIN_HASH (0x020)
173 #define WHS_END_HASH (0x040)
175 typedef void (*walk_hstore_cb)(void* /*arg*/, HStoreValue* /* value */,
176 uint32 /* flags */, uint32 /* level */);
177 extern void walkUncompressedHStore(HStoreValue *v,
178 walk_hstore_cb cb, void *cb_arg);
180 extern int compareHStoreStringValue(const void *a, const void *b, void *arg);
181 extern int compareHStorePair(const void *a, const void *b, void *arg);
183 extern int compareHStoreBinaryValue(char *a, char *b);
184 extern int compareHStoreValue(HStoreValue *a, HStoreValue *b);
186 extern HStoreValue* findUncompressedHStoreValueByValue(char *buffer,
190 extern HStoreValue* findUncompressedHStoreValue(char *buffer, uint32 flags,
192 char *key, uint32 keylen);
194 extern HStoreValue* getHStoreValue(char *buffer, uint32 flags, int32 i);
196 extern bool stringIsNumber(char *string, int len, bool jsonNumber);
198 typedef enum HStoreOutputKind {
201 ArrayCurlyBraces = 0x04,
202 RootHashDecorated = 0x08,
206 extern char* hstoreToCString(StringInfo out, char *in,
207 int len /* just estimation */,
208 HStoreOutputKind kind);
209 extern text* HStoreValueToText(HStoreValue *v);
211 typedef struct ToHStoreState
215 struct ToHStoreState *next;
218 extern HStoreValue* pushHStoreValue(ToHStoreState **state,
219 int r /* WHS_* */, HStoreValue *v);
220 extern void uniqueHStoreValue(HStoreValue *v);
221 extern uint32 compressHStore(HStoreValue *v, char *buffer);
224 typedef struct HStoreIterator
231 char *buffer; /* unparsed buffer */
236 * enum members should be freely OR'ed with HS_FLAG_ARRAY/HS_FLAG_HSTORE
237 * with possiblity of decoding. See optimization in HStoreIteratorGet()
246 struct HStoreIterator *next;
249 extern HStoreIterator* HStoreIteratorInit(char *buffer);
250 extern int /* WHS_* */ HStoreIteratorGet(HStoreIterator **it, HStoreValue *v,
253 #define HStoreContainsStrategyNumber 7
254 #define HStoreExistsStrategyNumber 9
255 #define HStoreExistsAnyStrategyNumber 10
256 #define HStoreExistsAllStrategyNumber 11
257 #define HStoreOldContainsStrategyNumber 13 /* backwards compatibility */
260 * defining HSTORE_POLLUTE_NAMESPACE=0 will prevent use of old function names;
261 * for now, we default to on for the benefit of people restoring old dumps
263 #ifndef HSTORE_POLLUTE_NAMESPACE
264 #define HSTORE_POLLUTE_NAMESPACE 1
267 #if HSTORE_POLLUTE_NAMESPACE
268 #define HSTORE_POLLUTE(newname_,oldname_) \
269 PG_FUNCTION_INFO_V1(oldname_); \
270 Datum oldname_(PG_FUNCTION_ARGS); \
271 Datum newname_(PG_FUNCTION_ARGS); \
272 Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \
273 extern int no_such_variable
275 #define HSTORE_POLLUTE(newname_,oldname_) \
276 extern int no_such_variable
280 * When using a GIN/GiST index for hstore, we choose to index both keys and values.
281 * The storage format is "text" values, with K, V, E or N prepended to the string
282 * to indicate key, value, element or null values. (As of 9.1 it might be better to
283 * store null values as nulls, but we'll keep it this way for on-disk
284 * compatibility.) Before nested hstore GIN indexes used KV notation, so there is
285 * no problem with upgrade, but GiST indexes should be rebuilded.
292 #endif /* __HSTORE_H__ */