1 /*
2  * contrib/hstore/hstore.h
3  */
4 #ifndef __HSTORE_H__
5 #define __HSTORE_H__
6 
7 #include "fmgr.h"
8 #include "utils/array.h"
9 
10 
11 /*
12  * HEntry: there is one of these for each key _and_ value in an hstore
13  *
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.
17  */
18 typedef struct
19 {
20 	uint32		entry;
21 } HEntry;
22 
23 #define HENTRY_ISFIRST 0x80000000
24 #define HENTRY_ISNULL  0x40000000
25 #define HENTRY_POSMASK 0x3FFFFFFF
26 
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_)	\
33 					  ? HSE_ENDPOS(he_) \
34 					  : HSE_ENDPOS(he_) - HSE_ENDPOS((&(he_))[-1]))
35 
36 /*
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
40  */
41 #define HSTORE_MAX_KEY_LEN 0x3FFFFFFF
42 #define HSTORE_MAX_VALUE_LEN 0x3FFFFFFF
43 
44 typedef struct
45 {
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 */
49 } HStore;
50 
51 /*
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.
58  */
59 #define HS_FLAG_NEWVERSION 0x80000000
60 
61 #define HS_COUNT(hsp_) ((hsp_)->size_ & 0x0FFFFFFF)
62 #define HS_SETCOUNT(hsp_,c_) ((hsp_)->size_ = (c_) | HS_FLAG_NEWVERSION)
63 
64 
65 /*
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.
70  */
71 #define HSHRDSIZE	(sizeof(HStore))
72 #define CALCDATASIZE(x, lenstr) ( (x) * 2 * sizeof(HEntry) + HSHRDSIZE + (lenstr) )
73 
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) )
77 
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]))
84 
85 /*
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.
90  */
91 
92 /*
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
97  * evaluation here.
98  */
99 #define HS_COPYITEM(dent_,dbuf_,dptr_,sptr_,klen_,vlen_,vnull_)			\
100 	do {																\
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));			\
106 	} while(0)
107 
108 /*
109  * add one key/item pair, from a Pairs structure, into an
110  * under-construction hstore
111  */
112 #define HS_ADDITEM(dent_,dbuf_,dptr_,pair_)								\
113 	do {																\
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)	\
119 								 | HENTRY_ISNULL);						\
120 		else															\
121 		{																\
122 			memcpy((dptr_), (pair_).val, (pair_).vallen);				\
123 			(dptr_) += (pair_).vallen;									\
124 			(dent_)++->entry = ((dptr_) - (dbuf_)) & HENTRY_POSMASK;	\
125 		}																\
126 	} while (0)
127 
128 /* finalize a newly-constructed hstore */
129 #define HS_FINALIZE(hsp_,count_,buf_,ptr_)							\
130 	do {															\
131 		int buflen = (ptr_) - (buf_);								\
132 		if ((count_))												\
133 			ARRPTR(hsp_)[0].entry |= HENTRY_ISFIRST;				\
134 		if ((count_) != HS_COUNT((hsp_)))							\
135 		{															\
136 			HS_SETCOUNT((hsp_),(count_));							\
137 			memmove(STRPTR(hsp_), (buf_), buflen);					\
138 		}															\
139 		SET_VARSIZE((hsp_), CALCDATASIZE((count_), buflen));		\
140 	} while (0)
141 
142 /* ensure the varlena size of an existing hstore is correct */
143 #define HS_FIXSIZE(hsp_,count_)											\
144 	do {																\
145 		int bl = (count_) ? HSE_ENDPOS(ARRPTR(hsp_)[2*(count_)-1]) : 0; \
146 		SET_VARSIZE((hsp_), CALCDATASIZE((count_),bl));					\
147 	} while (0)
148 
149 /* DatumGetHStoreP includes support for reading old-format hstore values */
150 extern HStore *hstoreUpgrade(Datum orig);
151 
152 #define DatumGetHStoreP(d) hstoreUpgrade(d)
153 
154 #define PG_GETARG_HS(x) DatumGetHStoreP(PG_GETARG_DATUM(x))
155 
156 
157 /*
158  * Pairs is a "decompressed" representation of one key/value pair.
159  * The two strings are not necessarily null-terminated.
160  */
161 typedef struct
162 {
163 	char	   *key;
164 	char	   *val;
165 	size_t		keylen;
166 	size_t		vallen;
167 	bool		isnull;			/* value is null? */
168 	bool		needfree;		/* need to pfree the value? */
169 } Pairs;
170 
171 extern int	hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen);
172 extern HStore *hstorePairs(Pairs *pairs, int32 pcount, int32 buflen);
173 
174 extern size_t hstoreCheckKeyLen(size_t len);
175 extern size_t hstoreCheckValLen(size_t len);
176 
177 extern int	hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen);
178 extern Pairs *hstoreArrayToPairs(ArrayType *a, int *npairs);
179 
180 #define HStoreContainsStrategyNumber	7
181 #define HStoreExistsStrategyNumber		9
182 #define HStoreExistsAnyStrategyNumber	10
183 #define HStoreExistsAllStrategyNumber	11
184 #define HStoreOldContainsStrategyNumber 13		/* backwards compatibility */
185 
186 /*
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
189  */
190 #ifndef HSTORE_POLLUTE_NAMESPACE
191 #define HSTORE_POLLUTE_NAMESPACE 1
192 #endif
193 
194 #if HSTORE_POLLUTE_NAMESPACE
195 #define HSTORE_POLLUTE(newname_,oldname_) \
196 	PG_FUNCTION_INFO_V1(oldname_);		  \
197 	Datum newname_(PG_FUNCTION_ARGS);	  \
198 	Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \
199 	extern int no_such_variable
200 #else
201 #define HSTORE_POLLUTE(newname_,oldname_) \
202 	extern int no_such_variable
203 #endif
204 
205 #endif   /* __HSTORE_H__ */
206