PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
hstore.h File Reference
#include "fmgr.h"
#include "utils/array.h"
Include dependency graph for hstore.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  HEntry
 
struct  HStore
 
struct  Pairs
 

Macros

#define HENTRY_ISFIRST   0x80000000
 
#define HENTRY_ISNULL   0x40000000
 
#define HENTRY_POSMASK   0x3FFFFFFF
 
#define HSE_ISFIRST(he_)   (((he_).entry & HENTRY_ISFIRST) != 0)
 
#define HSE_ISNULL(he_)   (((he_).entry & HENTRY_ISNULL) != 0)
 
#define HSE_ENDPOS(he_)   ((he_).entry & HENTRY_POSMASK)
 
#define HSE_OFF(he_)   (HSE_ISFIRST(he_) ? 0 : HSE_ENDPOS((&(he_))[-1]))
 
#define HSE_LEN(he_)
 
#define HSTORE_MAX_KEY_LEN   0x3FFFFFFF
 
#define HSTORE_MAX_VALUE_LEN   0x3FFFFFFF
 
#define HS_FLAG_NEWVERSION   0x80000000
 
#define HS_COUNT(hsp_)   ((hsp_)->size_ & 0x0FFFFFFF)
 
#define HS_SETCOUNT(hsp_, c_)   ((hsp_)->size_ = (c_) | HS_FLAG_NEWVERSION)
 
#define HSHRDSIZE   (sizeof(HStore))
 
#define CALCDATASIZE(x, lenstr)   ( (x) * 2 * sizeof(HEntry) + HSHRDSIZE + (lenstr) )
 
#define ARRPTR(x)   ( (HEntry*) ( (HStore*)(x) + 1 ) )
 
#define STRPTR(x)   ( (char*)(ARRPTR(x) + HS_COUNT((HStore*)(x)) * 2) )
 
#define HSTORE_KEY(arr_, str_, i_)   ((str_) + HSE_OFF((arr_)[2*(i_)]))
 
#define HSTORE_VAL(arr_, str_, i_)   ((str_) + HSE_OFF((arr_)[2*(i_)+1]))
 
#define HSTORE_KEYLEN(arr_, i_)   (HSE_LEN((arr_)[2*(i_)]))
 
#define HSTORE_VALLEN(arr_, i_)   (HSE_LEN((arr_)[2*(i_)+1]))
 
#define HSTORE_VALISNULL(arr_, i_)   (HSE_ISNULL((arr_)[2*(i_)+1]))
 
#define HS_COPYITEM(dent_, dbuf_, dptr_, sptr_, klen_, vlen_, vnull_)
 
#define HS_ADDITEM(dent_, dbuf_, dptr_, pair_)
 
#define HS_FINALIZE(hsp_, count_, buf_, ptr_)
 
#define HS_FIXSIZE(hsp_, count_)
 
#define DatumGetHStoreP(d)   hstoreUpgrade(d)
 
#define PG_GETARG_HS(x)   DatumGetHStoreP(PG_GETARG_DATUM(x))
 
#define HStoreContainsStrategyNumber   7
 
#define HStoreExistsStrategyNumber   9
 
#define HStoreExistsAnyStrategyNumber   10
 
#define HStoreExistsAllStrategyNumber   11
 
#define HStoreOldContainsStrategyNumber   13 /* backwards compatibility */
 
#define HSTORE_POLLUTE_NAMESPACE   1
 
#define HSTORE_POLLUTE(newname_, oldname_)
 

Functions

HStorehstoreUpgrade (Datum orig)
 
int hstoreUniquePairs (Pairs *a, int32 l, int32 *buflen)
 
HStorehstorePairs (Pairs *pairs, int32 pcount, int32 buflen)
 
size_t hstoreCheckKeyLen (size_t len)
 
size_t hstoreCheckValLen (size_t len)
 
int hstoreFindKey (HStore *hs, int *lowbound, char *key, int keylen)
 
PairshstoreArrayToPairs (ArrayType *a, int *npairs)
 

Macro Definition Documentation

#define ARRPTR (   x)    ( (HEntry*) ( (HStore*)(x) + 1 ) )

Definition at line 75 of file hstore.h.

#define DatumGetHStoreP (   d)    hstoreUpgrade(d)

Definition at line 152 of file hstore.h.

Referenced by ghstore_compress().

#define HENTRY_ISFIRST   0x80000000

Definition at line 23 of file hstore.h.

Referenced by hstoreUpgrade().

#define HENTRY_ISNULL   0x40000000

Definition at line 24 of file hstore.h.

Referenced by hstoreUpgrade().

#define HENTRY_POSMASK   0x3FFFFFFF

Definition at line 25 of file hstore.h.

Referenced by hstoreUpgrade().

#define HS_ADDITEM (   dent_,
  dbuf_,
  dptr_,
  pair_ 
)
Value:
do { \
memcpy((dptr_), (pair_).key, (pair_).keylen); \
(dptr_) += (pair_).keylen; \
(dent_)++->entry = ((dptr_) - (dbuf_)) & HENTRY_POSMASK; \
if ((pair_).isnull) \
(dent_)++->entry = ((((dptr_) - (dbuf_)) & HENTRY_POSMASK) \
else \
{ \
memcpy((dptr_), (pair_).val, (pair_).vallen); \
(dptr_) += (pair_).vallen; \
(dent_)++->entry = ((dptr_) - (dbuf_)) & HENTRY_POSMASK; \
} \
} while (0)
#define HENTRY_POSMASK
Definition: hstore.h:25
#define HENTRY_ISNULL
Definition: hstore.h:24
long val
Definition: informix.c:689

Definition at line 112 of file hstore.h.

Referenced by hstorePairs().

#define HS_COPYITEM (   dent_,
  dbuf_,
  dptr_,
  sptr_,
  klen_,
  vlen_,
  vnull_ 
)
Value:
do { \
memcpy((dptr_), (sptr_), (klen_)+(vlen_)); \
(dptr_) += (klen_)+(vlen_); \
(dent_)++->entry = ((dptr_) - (dbuf_) - (vlen_)) & HENTRY_POSMASK; \
(dent_)++->entry = ((((dptr_) - (dbuf_)) & HENTRY_POSMASK) \
| ((vnull_) ? HENTRY_ISNULL : 0)); \
} while(0)
#define HENTRY_POSMASK
Definition: hstore.h:25
#define HENTRY_ISNULL
Definition: hstore.h:24

Definition at line 99 of file hstore.h.

Referenced by hstore_concat(), hstore_delete(), hstore_delete_array(), and hstore_delete_hstore().

#define HS_FINALIZE (   hsp_,
  count_,
  buf_,
  ptr_ 
)
Value:
do { \
int buflen = (ptr_) - (buf_); \
if ((count_)) \
ARRPTR(hsp_)[0].entry |= HENTRY_ISFIRST; \
if ((count_) != HS_COUNT((hsp_))) \
{ \
HS_SETCOUNT((hsp_),(count_)); \
memmove(STRPTR(hsp_), (buf_), buflen); \
} \
SET_VARSIZE((hsp_), CALCDATASIZE((count_), buflen)); \
} while (0)
#define ARRPTR(x)
Definition: hstore.h:75
#define memmove(d, s, c)
Definition: c.h:1058
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
#define HENTRY_ISFIRST
Definition: hstore.h:23
#define STRPTR(x)
Definition: hstore.h:76
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62

Definition at line 129 of file hstore.h.

Referenced by hstore_concat(), hstore_delete(), hstore_delete_array(), hstore_delete_hstore(), and hstorePairs().

#define HS_FIXSIZE (   hsp_,
  count_ 
)
Value:
do { \
int bl = (count_) ? HSE_ENDPOS(ARRPTR(hsp_)[2*(count_)-1]) : 0; \
SET_VARSIZE((hsp_), CALCDATASIZE((count_),bl)); \
} while (0)
#define HSE_ENDPOS(he_)
Definition: hstore.h:30
#define ARRPTR(x)
Definition: hstore.h:75
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328

Definition at line 143 of file hstore.h.

Referenced by hstore_concat(), hstore_delete_array(), hstore_delete_hstore(), and hstoreUpgrade().

#define HS_FLAG_NEWVERSION   0x80000000

Definition at line 59 of file hstore.h.

Referenced by hstoreUpgrade(), hstoreValidNewFormat(), and hstoreValidOldFormat().

#define HS_SETCOUNT (   hsp_,
  c_ 
)    ((hsp_)->size_ = (c_) | HS_FLAG_NEWVERSION)
#define HSE_ENDPOS (   he_)    ((he_).entry & HENTRY_POSMASK)

Definition at line 30 of file hstore.h.

Referenced by hstore_cmp(), hstore_hash(), and hstoreValidNewFormat().

#define HSE_ISFIRST (   he_)    (((he_).entry & HENTRY_ISFIRST) != 0)

Definition at line 28 of file hstore.h.

Referenced by hstoreUpgrade(), and hstoreValidNewFormat().

#define HSE_ISNULL (   he_)    (((he_).entry & HENTRY_ISNULL) != 0)

Definition at line 29 of file hstore.h.

Referenced by hstore_cmp(), and hstoreValidNewFormat().

#define HSE_LEN (   he_)
Value:
(HSE_ISFIRST(he_) \
? HSE_ENDPOS(he_) \
: HSE_ENDPOS(he_) - HSE_ENDPOS((&(he_))[-1]))
#define HSE_ENDPOS(he_)
Definition: hstore.h:30
#define HSE_ISFIRST(he_)
Definition: hstore.h:28

Definition at line 32 of file hstore.h.

#define HSE_OFF (   he_)    (HSE_ISFIRST(he_) ? 0 : HSE_ENDPOS((&(he_))[-1]))

Definition at line 31 of file hstore.h.

#define HSHRDSIZE   (sizeof(HStore))

Definition at line 71 of file hstore.h.

Referenced by hstore_concat(), and hstore_hash().

#define HSTORE_MAX_KEY_LEN   0x3FFFFFFF

Definition at line 41 of file hstore.h.

Referenced by hstoreCheckKeyLen().

#define HSTORE_MAX_VALUE_LEN   0x3FFFFFFF

Definition at line 42 of file hstore.h.

Referenced by hstoreCheckValLen().

#define HSTORE_POLLUTE (   newname_,
  oldname_ 
)
Value:
Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \
extern int no_such_variable
uintptr_t Datum
Definition: postgres.h:372
#define PG_FUNCTION_INFO_V1(funcname)
Definition: fmgr.h:373
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158

Definition at line 195 of file hstore.h.

#define HSTORE_POLLUTE_NAMESPACE   1

Definition at line 191 of file hstore.h.

#define HStoreContainsStrategyNumber   7

Definition at line 180 of file hstore.h.

Referenced by ghstore_consistent(), gin_consistent_hstore(), and gin_extract_hstore_query().

#define HStoreExistsAllStrategyNumber   11

Definition at line 183 of file hstore.h.

Referenced by ghstore_consistent(), gin_consistent_hstore(), and gin_extract_hstore_query().

#define HStoreExistsAnyStrategyNumber   10

Definition at line 182 of file hstore.h.

Referenced by ghstore_consistent(), gin_consistent_hstore(), and gin_extract_hstore_query().

#define HStoreExistsStrategyNumber   9

Definition at line 181 of file hstore.h.

Referenced by ghstore_consistent(), gin_consistent_hstore(), and gin_extract_hstore_query().

#define HStoreOldContainsStrategyNumber   13 /* backwards compatibility */

Definition at line 184 of file hstore.h.

Referenced by ghstore_consistent().

Function Documentation

Pairs* hstoreArrayToPairs ( ArrayType a,
int *  npairs 
)

Definition at line 74 of file hstore_op.c.

References deconstruct_array(), ereport, errcode(), errmsg(), ERROR, hstoreUniquePairs, i, Pairs::isnull, Pairs::key, Pairs::keylen, MaxAllocSize, Pairs::needfree, NULL, palloc(), TEXTOID, Pairs::val, Pairs::vallen, VARDATA, VARHDRSZ, and VARSIZE.

Referenced by hstore_delete_array(), hstore_exists_all(), hstore_exists_any(), and hstore_slice_to_hstore().

75 {
76  Datum *key_datums;
77  bool *key_nulls;
78  int key_count;
79  Pairs *key_pairs;
80  int bufsiz;
81  int i,
82  j;
83 
85  TEXTOID, -1, false, 'i',
86  &key_datums, &key_nulls, &key_count);
87 
88  if (key_count == 0)
89  {
90  *npairs = 0;
91  return NULL;
92  }
93 
94  /*
95  * A text array uses at least eight bytes per element, so any overflow in
96  * "key_count * sizeof(Pairs)" is small enough for palloc() to catch.
97  * However, credible improvements to the array format could invalidate
98  * that assumption. Therefore, use an explicit check rather than relying
99  * on palloc() to complain.
100  */
101  if (key_count > MaxAllocSize / sizeof(Pairs))
102  ereport(ERROR,
103  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
104  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
105  key_count, (int) (MaxAllocSize / sizeof(Pairs)))));
106 
107  key_pairs = palloc(sizeof(Pairs) * key_count);
108 
109  for (i = 0, j = 0; i < key_count; i++)
110  {
111  if (!key_nulls[i])
112  {
113  key_pairs[j].key = VARDATA(key_datums[i]);
114  key_pairs[j].keylen = VARSIZE(key_datums[i]) - VARHDRSZ;
115  key_pairs[j].val = NULL;
116  key_pairs[j].vallen = 0;
117  key_pairs[j].needfree = 0;
118  key_pairs[j].isnull = 1;
119  j++;
120  }
121  }
122 
123  *npairs = hstoreUniquePairs(key_pairs, j, &bufsiz);
124 
125  return key_pairs;
126 }
#define VARDATA(PTR)
Definition: postgres.h:303
#define TEXTOID
Definition: pg_type.h:324
#define VARSIZE(PTR)
Definition: postgres.h:304
#define VARHDRSZ
Definition: c.h:445
int errcode(int sqlerrcode)
Definition: elog.c:575
size_t vallen
Definition: hstore.h:166
bool needfree
Definition: hstore.h:168
char * val
Definition: hstore.h:164
char * key
Definition: hstore.h:163
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define MaxAllocSize
Definition: memutils.h:40
#define hstoreUniquePairs
Definition: hstore_plperl.c:59
uintptr_t Datum
Definition: postgres.h:372
size_t keylen
Definition: hstore.h:165
#define NULL
Definition: c.h:229
bool isnull
Definition: hstore.h:167
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3475
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
Definition: hstore.h:161
size_t hstoreCheckKeyLen ( size_t  len)

Definition at line 354 of file hstore_io.c.

References ereport, errcode(), errmsg(), ERROR, and HSTORE_MAX_KEY_LEN.

Referenced by hstore_from_array(), hstore_from_arrays(), hstore_from_record(), hstore_from_text(), hstore_recv(), and parse_hstore().

355 {
356  if (len > HSTORE_MAX_KEY_LEN)
357  ereport(ERROR,
358  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
359  errmsg("string too long for hstore key")));
360  return len;
361 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define HSTORE_MAX_KEY_LEN
Definition: hstore.h:41
int errmsg(const char *fmt,...)
Definition: elog.c:797
size_t hstoreCheckValLen ( size_t  len)

Definition at line 364 of file hstore_io.c.

References ereport, errcode(), errmsg(), ERROR, and HSTORE_MAX_VALUE_LEN.

Referenced by hstore_from_array(), hstore_from_arrays(), hstore_from_record(), hstore_from_text(), hstore_recv(), and parse_hstore().

365 {
366  if (len > HSTORE_MAX_VALUE_LEN)
367  ereport(ERROR,
368  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
369  errmsg("string too long for hstore value")));
370  return len;
371 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define HSTORE_MAX_VALUE_LEN
Definition: hstore.h:42
int hstoreFindKey ( HStore hs,
int *  lowbound,
char *  key,
int  keylen 
)

Definition at line 37 of file hstore_op.c.

References ARRPTR, difference(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, and STRPTR.

Referenced by hstore_contains(), hstore_defined(), hstore_exists(), hstore_exists_all(), hstore_exists_any(), hstore_fetchval(), hstore_populate_record(), hstore_slice_to_array(), and hstore_slice_to_hstore().

38 {
39  HEntry *entries = ARRPTR(hs);
40  int stopLow = lowbound ? *lowbound : 0;
41  int stopHigh = HS_COUNT(hs);
42  int stopMiddle;
43  char *base = STRPTR(hs);
44 
45  while (stopLow < stopHigh)
46  {
47  int difference;
48 
49  stopMiddle = stopLow + (stopHigh - stopLow) / 2;
50 
51  if (HSTORE_KEYLEN(entries, stopMiddle) == keylen)
52  difference = memcmp(HSTORE_KEY(entries, base, stopMiddle), key, keylen);
53  else
54  difference = (HSTORE_KEYLEN(entries, stopMiddle) > keylen) ? 1 : -1;
55 
56  if (difference == 0)
57  {
58  if (lowbound)
59  *lowbound = stopMiddle + 1;
60  return stopMiddle;
61  }
62  else if (difference < 0)
63  stopLow = stopMiddle + 1;
64  else
65  stopHigh = stopMiddle;
66  }
67 
68  if (lowbound)
69  *lowbound = stopLow;
70  return -1;
71 }
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
Datum difference(PG_FUNCTION_ARGS)
Definition: hstore.h:18
#define STRPTR(x)
Definition: hstore.h:76
#define ARRPTR(x)
Definition: cube.c:26
HStore* hstorePairs ( Pairs pairs,
int32  pcount,
int32  buflen 
)

Definition at line 375 of file hstore_io.c.

References ARRPTR, buf, CALCDATASIZE, HS_ADDITEM, HS_FINALIZE, HS_SETCOUNT, i, palloc(), SET_VARSIZE, and STRPTR.

Referenced by hstore_from_array(), hstore_from_arrays(), hstore_from_record(), hstore_from_text(), hstore_in(), and hstore_recv().

376 {
377  HStore *out;
378  HEntry *entry;
379  char *ptr;
380  char *buf;
381  int32 len;
382  int32 i;
383 
384  len = CALCDATASIZE(pcount, buflen);
385  out = palloc(len);
386  SET_VARSIZE(out, len);
387  HS_SETCOUNT(out, pcount);
388 
389  if (pcount == 0)
390  return out;
391 
392  entry = ARRPTR(out);
393  buf = ptr = STRPTR(out);
394 
395  for (i = 0; i < pcount; i++)
396  HS_ADDITEM(entry, buf, ptr, pairs[i]);
397 
398  HS_FINALIZE(out, pcount, buf, ptr);
399 
400  return out;
401 }
Definition: hstore.h:44
signed int int32
Definition: c.h:256
static char * buf
Definition: pg_test_fsync.c:65
#define HS_ADDITEM(dent_, dbuf_, dptr_, pair_)
Definition: hstore.h:112
#define HS_FINALIZE(hsp_, count_, buf_, ptr_)
Definition: hstore.h:129
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
Definition: hstore.h:18
void * palloc(Size size)
Definition: mcxt.c:849
#define STRPTR(x)
Definition: hstore.h:76
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328
#define ARRPTR(x)
Definition: cube.c:26
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62
int hstoreUniquePairs ( Pairs a,
int32  l,
int32 buflen 
)

Definition at line 312 of file hstore_io.c.

References comparePairs(), Pairs::isnull, Pairs::key, Pairs::keylen, Pairs::needfree, pfree(), qsort, Pairs::val, and Pairs::vallen.

Referenced by hstore_from_array(), hstore_from_arrays(), hstore_from_record(), hstore_in(), and hstore_recv().

313 {
314  Pairs *ptr,
315  *res;
316 
317  *buflen = 0;
318  if (l < 2)
319  {
320  if (l == 1)
321  *buflen = a->keylen + ((a->isnull) ? 0 : a->vallen);
322  return l;
323  }
324 
325  qsort((void *) a, l, sizeof(Pairs), comparePairs);
326  ptr = a + 1;
327  res = a;
328  while (ptr - a < l)
329  {
330  if (ptr->keylen == res->keylen &&
331  memcmp(ptr->key, res->key, res->keylen) == 0)
332  {
333  if (ptr->needfree)
334  {
335  pfree(ptr->key);
336  pfree(ptr->val);
337  }
338  }
339  else
340  {
341  *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
342  res++;
343  memcpy(res, ptr, sizeof(Pairs));
344  }
345 
346  ptr++;
347  }
348 
349  *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
350  return res + 1 - a;
351 }
size_t vallen
Definition: hstore.h:166
bool needfree
Definition: hstore.h:168
char * val
Definition: hstore.h:164
char * key
Definition: hstore.h:163
void pfree(void *pointer)
Definition: mcxt.c:950
static int comparePairs(const void *a, const void *b)
Definition: hstore_io.c:282
size_t keylen
Definition: hstore.h:165
bool isnull
Definition: hstore.h:167
#define qsort(a, b, c, d)
Definition: port.h:440
Definition: hstore.h:161
HStore* hstoreUpgrade ( Datum  orig)

Definition at line 236 of file hstore_compat.c.

References ARRPTR, DatumGetPointer, elog, HEntry::entry, ERROR, HENTRY_ISFIRST, HENTRY_ISNULL, HENTRY_POSMASK, HS_COUNT, HS_FIXSIZE, HS_FLAG_NEWVERSION, HS_SETCOUNT, HSE_ISFIRST, hstoreValidNewFormat(), hstoreValidOldFormat(), i, HOldEntry::keylen, PG_DETOAST_DATUM, PG_DETOAST_DATUM_COPY, HOldEntry::pos, HStore::size_, HOldEntry::valisnull, HOldEntry::vallen, VARSIZE, and WARNING.

237 {
238  HStore *hs = (HStore *) PG_DETOAST_DATUM(orig);
239  int valid_new;
240  int valid_old;
241  bool writable;
242 
243  /* Return immediately if no conversion needed */
244  if ((hs->size_ & HS_FLAG_NEWVERSION) ||
245  hs->size_ == 0 ||
246  (VARSIZE(hs) < 32768 && HSE_ISFIRST((ARRPTR(hs)[0]))))
247  return hs;
248 
249  valid_new = hstoreValidNewFormat(hs);
250  valid_old = hstoreValidOldFormat(hs);
251  /* Do we have a writable copy? */
252  writable = ((void *) hs != (void *) DatumGetPointer(orig));
253 
254  if (!valid_old || hs->size_ == 0)
255  {
256  if (valid_new)
257  {
258  /*
259  * force the "new version" flag and the correct varlena length,
260  * but only if we have a writable copy already (which we almost
261  * always will, since short new-format values won't come through
262  * here)
263  */
264  if (writable)
265  {
266  HS_SETCOUNT(hs, HS_COUNT(hs));
267  HS_FIXSIZE(hs, HS_COUNT(hs));
268  }
269  return hs;
270  }
271  else
272  {
273  elog(ERROR, "invalid hstore value found");
274  }
275  }
276 
277  /*
278  * this is the tricky edge case. It is only possible in some quite extreme
279  * cases (the hstore must have had a lot of wasted padding space at the
280  * end). But the only way a "new" hstore value could get here is if we're
281  * upgrading in place from a pre-release version of hstore-new (NOT
282  * contrib/hstore), so we work off the following assumptions: 1. If you're
283  * moving from old contrib/hstore to hstore-new, you're required to fix up
284  * any potential conflicts first, e.g. by running ALTER TABLE ... USING
285  * col::text::hstore; on all hstore columns before upgrading. 2. If you're
286  * moving from old contrib/hstore to new contrib/hstore, then "new" values
287  * are impossible here 3. If you're moving from pre-release hstore-new to
288  * hstore-new, then "old" values are impossible here 4. If you're moving
289  * from pre-release hstore-new to new contrib/hstore, you're not doing so
290  * as an in-place upgrade, so there is no issue So the upshot of all this
291  * is that we can treat all the edge cases as "new" if we're being built
292  * as hstore-new, and "old" if we're being built as contrib/hstore.
293  *
294  * XXX the WARNING can probably be downgraded to DEBUG1 once this has been
295  * beta-tested. But for now, it would be very useful to know if anyone can
296  * actually reach this case in a non-contrived setting.
297  */
298 
299  if (valid_new)
300  {
301 #if HSTORE_IS_HSTORE_NEW
302  elog(WARNING, "ambiguous hstore value resolved as hstore-new");
303 
304  /*
305  * force the "new version" flag and the correct varlena length, but
306  * only if we have a writable copy already (which we almost always
307  * will, since short new-format values won't come through here)
308  */
309  if (writable)
310  {
311  HS_SETCOUNT(hs, HS_COUNT(hs));
312  HS_FIXSIZE(hs, HS_COUNT(hs));
313  }
314  return hs;
315 #else
316  elog(WARNING, "ambiguous hstore value resolved as hstore-old");
317 #endif
318  }
319 
320  /*
321  * must have an old-style value. Overwrite it in place as a new-style one,
322  * making sure we have a writable copy first.
323  */
324 
325  if (!writable)
326  hs = (HStore *) PG_DETOAST_DATUM_COPY(orig);
327 
328  {
329  int count = hs->size_;
330  HEntry *new_entries = ARRPTR(hs);
331  HOldEntry *old_entries = (HOldEntry *) ARRPTR(hs);
332  int i;
333 
334  for (i = 0; i < count; ++i)
335  {
336  uint32 pos = old_entries[i].pos;
337  uint32 keylen = old_entries[i].keylen;
338  uint32 vallen = old_entries[i].vallen;
339  bool isnull = old_entries[i].valisnull;
340 
341  if (isnull)
342  vallen = 0;
343 
344  new_entries[2 * i].entry = (pos + keylen) & HENTRY_POSMASK;
345  new_entries[2 * i + 1].entry = (((pos + keylen + vallen) & HENTRY_POSMASK)
346  | ((isnull) ? HENTRY_ISNULL : 0));
347  }
348 
349  if (count)
350  new_entries[0].entry |= HENTRY_ISFIRST;
351  HS_SETCOUNT(hs, count);
352  HS_FIXSIZE(hs, count);
353  }
354 
355  return hs;
356 }
Definition: hstore.h:44
#define HENTRY_POSMASK
Definition: hstore.h:25
#define PG_DETOAST_DATUM_COPY(datum)
Definition: fmgr.h:207
#define VARSIZE(PTR)
Definition: postgres.h:304
#define HSE_ISFIRST(he_)
Definition: hstore.h:28
#define HENTRY_ISNULL
Definition: hstore.h:24
static int hstoreValidNewFormat(HStore *hs)
uint16 keylen
#define ERROR
Definition: elog.h:43
#define HS_FLAG_NEWVERSION
Definition: hstore.h:59
#define HS_COUNT(hsp_)
Definition: hstore.h:61
uint16 vallen
uint32 entry
Definition: hstore.h:20
unsigned int uint32
Definition: c.h:268
#define WARNING
Definition: elog.h:40
static int hstoreValidOldFormat(HStore *hs)
#define HENTRY_ISFIRST
Definition: hstore.h:23
uint32 valisnull
uint32 pos
Definition: hstore.h:18
#define DatumGetPointer(X)
Definition: postgres.h:555
uint32 size_
Definition: hstore.h:47
int i
#define PG_DETOAST_DATUM(datum)
Definition: fmgr.h:205
#define ARRPTR(x)
Definition: cube.c:26
#define elog
Definition: elog.h:219
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62
#define HS_FIXSIZE(hsp_, count_)
Definition: hstore.h:143