#include "fmgr.h"
#include "utils/array.h"
Go to the source code of this file.
Data Structures | |
struct | HEntry |
struct | HStore |
struct | Pairs |
Defines | |
#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 | HS_KEY(arr_, str_, i_) ((str_) + HSE_OFF((arr_)[2*(i_)])) |
#define | HS_VAL(arr_, str_, i_) ((str_) + HSE_OFF((arr_)[2*(i_)+1])) |
#define | HS_KEYLEN(arr_, i_) (HSE_LEN((arr_)[2*(i_)])) |
#define | HS_VALLEN(arr_, i_) (HSE_LEN((arr_)[2*(i_)+1])) |
#define | HS_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 |
#define | HSTORE_POLLUTE_NAMESPACE 1 |
#define | HSTORE_POLLUTE(newname_, oldname_) |
Functions | |
HStore * | hstoreUpgrade (Datum orig) |
int | hstoreUniquePairs (Pairs *a, int32 l, int32 *buflen) |
HStore * | hstorePairs (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) |
Pairs * | hstoreArrayToPairs (ArrayType *a, int *npairs) |
#define CALCDATASIZE | ( | x, | ||
lenstr | ||||
) | ( (x) * 2 * sizeof(HEntry) + HSHRDSIZE + (lenstr) ) |
Definition at line 63 of file hstore.h.
Referenced by hstore_hash(), hstorePairs(), hstoreValidNewFormat(), hstoreValidOldFormat(), make_tsvector(), to_tsvector_byid(), tsvector_concat(), tsvector_strip(), tsvector_update_trigger(), and tsvectorin().
#define DatumGetHStoreP | ( | d | ) | hstoreUpgrade(d) |
Definition at line 143 of file hstore.h.
Referenced by ghstore_compress().
#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_ | ||||
) |
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) \ | HENTRY_ISNULL); \ else \ { \ memcpy((dptr_), (pair_).val, (pair_).vallen); \ (dptr_) += (pair_).vallen; \ (dent_)++->entry = ((dptr_) - (dbuf_)) & HENTRY_POSMASK; \ } \ } while (0)
Definition at line 103 of file hstore.h.
Referenced by hstorePairs().
#define HS_COPYITEM | ( | dent_, | ||
dbuf_, | ||||
dptr_, | ||||
sptr_, | ||||
klen_, | ||||
vlen_, | ||||
vnull_ | ||||
) |
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)
Definition at line 90 of file hstore.h.
Referenced by hstore_concat(), hstore_delete(), hstore_delete_array(), and hstore_delete_hstore().
#define HS_COUNT | ( | hsp_ | ) | ((hsp_)->size_ & 0x0FFFFFFF) |
Definition at line 58 of file hstore.h.
Referenced by ghstore_compress(), ghstore_consistent(), gin_extract_hstore(), hstore_akeys(), hstore_avals(), hstore_cmp(), hstore_concat(), hstore_contains(), hstore_delete(), hstore_delete_array(), hstore_delete_hstore(), hstore_each(), hstore_hash(), hstore_out(), hstore_populate_record(), hstore_send(), hstore_skeys(), hstore_svals(), hstore_to_array_internal(), hstore_to_json(), hstore_to_json_loose(), hstoreFindKey(), hstoreUpgrade(), and hstoreValidNewFormat().
#define HS_FINALIZE | ( | hsp_, | ||
count_, | ||||
buf_, | ||||
ptr_ | ||||
) |
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)
Definition at line 120 of file hstore.h.
Referenced by hstore_concat(), hstore_delete(), hstore_delete_array(), hstore_delete_hstore(), and hstorePairs().
#define HS_FIXSIZE | ( | hsp_, | ||
count_ | ||||
) |
do { \ int bl = (count_) ? HSE_ENDPOS(ARRPTR(hsp_)[2*(count_)-1]) : 0; \ SET_VARSIZE((hsp_), CALCDATASIZE((count_),bl)); \ } while (0)
Definition at line 134 of file hstore.h.
Referenced by hstore_concat(), hstore_delete_array(), hstore_delete_hstore(), and hstoreUpgrade().
#define HS_FLAG_NEWVERSION 0x80000000 |
Definition at line 56 of file hstore.h.
Referenced by hstoreUpgrade(), hstoreValidNewFormat(), and hstoreValidOldFormat().
#define HS_KEY | ( | arr_, | ||
str_, | ||||
i_ | ||||
) | ((str_) + HSE_OFF((arr_)[2*(i_)])) |
Definition at line 70 of file hstore.h.
Referenced by ghstore_compress(), ghstore_consistent(), gin_extract_hstore(), hstore_akeys(), hstore_concat(), hstore_contains(), hstore_delete(), hstore_delete_array(), hstore_delete_hstore(), hstore_each(), hstore_out(), hstore_send(), hstore_skeys(), hstore_to_array_internal(), hstore_to_json(), hstore_to_json_loose(), and hstoreFindKey().
#define HS_KEYLEN | ( | arr_, | ||
i_ | ||||
) | (HSE_LEN((arr_)[2*(i_)])) |
Definition at line 72 of file hstore.h.
Referenced by ghstore_compress(), ghstore_consistent(), gin_extract_hstore(), hstore_akeys(), hstore_concat(), hstore_contains(), hstore_delete(), hstore_delete_array(), hstore_delete_hstore(), hstore_each(), hstore_out(), hstore_send(), hstore_skeys(), hstore_to_array_internal(), hstore_to_json(), hstore_to_json_loose(), hstoreFindKey(), and hstoreValidNewFormat().
#define HS_SETCOUNT | ( | hsp_, | ||
c_ | ||||
) | ((hsp_)->size_ = (c_) | HS_FLAG_NEWVERSION) |
Definition at line 59 of file hstore.h.
Referenced by hstore_concat(), hstore_delete(), hstore_delete_array(), hstore_delete_hstore(), hstorePairs(), and hstoreUpgrade().
#define HS_VAL | ( | arr_, | ||
str_, | ||||
i_ | ||||
) | ((str_) + HSE_OFF((arr_)[2*(i_)+1])) |
Definition at line 71 of file hstore.h.
Referenced by ghstore_compress(), ghstore_consistent(), gin_extract_hstore(), hstore_avals(), hstore_contains(), hstore_delete_hstore(), hstore_each(), hstore_fetchval(), hstore_out(), hstore_populate_record(), hstore_send(), hstore_slice_to_array(), hstore_slice_to_hstore(), hstore_svals(), hstore_to_array_internal(), hstore_to_json(), and hstore_to_json_loose().
#define HS_VALISNULL | ( | arr_, | ||
i_ | ||||
) | (HSE_ISNULL((arr_)[2*(i_)+1])) |
Definition at line 74 of file hstore.h.
Referenced by ghstore_compress(), ghstore_consistent(), gin_extract_hstore(), hstore_avals(), hstore_concat(), hstore_contains(), hstore_defined(), hstore_delete(), hstore_delete_array(), hstore_delete_hstore(), hstore_each(), hstore_fetchval(), hstore_out(), hstore_populate_record(), hstore_send(), hstore_slice_to_array(), hstore_slice_to_hstore(), hstore_svals(), hstore_to_array_internal(), hstore_to_json(), and hstore_to_json_loose().
#define HS_VALLEN | ( | arr_, | ||
i_ | ||||
) | (HSE_LEN((arr_)[2*(i_)+1])) |
Definition at line 73 of file hstore.h.
Referenced by ghstore_compress(), ghstore_consistent(), gin_extract_hstore(), hstore_avals(), hstore_concat(), hstore_contains(), hstore_delete(), hstore_delete_array(), hstore_delete_hstore(), hstore_each(), hstore_fetchval(), hstore_out(), hstore_populate_record(), hstore_send(), hstore_slice_to_array(), hstore_slice_to_hstore(), hstore_svals(), hstore_to_array_internal(), hstore_to_json(), and hstore_to_json_loose().
#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_ | ) |
(HSE_ISFIRST(he_) \ ? HSE_ENDPOS(he_) \ : HSE_ENDPOS(he_) - HSE_ENDPOS((&(he_))[-1]))
#define HSE_OFF | ( | he_ | ) | (HSE_ISFIRST(he_) ? 0 : HSE_ENDPOS((&(he_))[-1])) |
#define HSHRDSIZE (sizeof(HStore)) |
Definition at line 62 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_ | ||||
) |
PG_FUNCTION_INFO_V1(oldname_); \ Datum oldname_(PG_FUNCTION_ARGS); \ Datum newname_(PG_FUNCTION_ARGS); \ Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \ extern int no_such_variable
#define HStoreContainsStrategyNumber 7 |
Definition at line 171 of file hstore.h.
Referenced by ghstore_consistent(), gin_consistent_hstore(), and gin_extract_hstore_query().
#define HStoreExistsAllStrategyNumber 11 |
Definition at line 174 of file hstore.h.
Referenced by ghstore_consistent(), gin_consistent_hstore(), and gin_extract_hstore_query().
#define HStoreExistsAnyStrategyNumber 10 |
Definition at line 173 of file hstore.h.
Referenced by ghstore_consistent(), gin_consistent_hstore(), and gin_extract_hstore_query().
#define HStoreExistsStrategyNumber 9 |
Definition at line 172 of file hstore.h.
Referenced by ghstore_consistent(), gin_consistent_hstore(), and gin_extract_hstore_query().
#define HStoreOldContainsStrategyNumber 13 |
Definition at line 175 of file hstore.h.
Referenced by ghstore_consistent().
#define PG_GETARG_HS | ( | x | ) | DatumGetHStoreP(PG_GETARG_DATUM(x)) |
Definition at line 145 of file hstore.h.
Referenced by ghstore_consistent(), gin_extract_hstore(), hstore_akeys(), hstore_avals(), hstore_cmp(), hstore_concat(), hstore_contains(), hstore_defined(), hstore_delete(), hstore_delete_array(), hstore_delete_hstore(), hstore_each(), hstore_exists(), hstore_exists_all(), hstore_exists_any(), hstore_fetchval(), hstore_hash(), hstore_out(), hstore_populate_record(), hstore_send(), hstore_skeys(), hstore_slice_to_array(), hstore_slice_to_hstore(), hstore_svals(), hstore_to_array(), hstore_to_json(), hstore_to_json_loose(), and hstore_to_matrix().
#define STRPTR | ( | x | ) | ( (char*)(ARRPTR(x) + HS_COUNT((HStore*)(x)) * 2) ) |
Definition at line 67 of file hstore.h.
Referenced by cnt_length(), compute_tsvector_stats(), find_wordentry(), ghstore_compress(), ghstore_consistent(), gin_extract_hstore(), gin_extract_tsvector(), gtsvector_compress(), hstore_akeys(), hstore_avals(), hstore_cmp(), hstore_concat(), hstore_contains(), hstore_delete(), hstore_delete_array(), hstore_delete_hstore(), hstore_each(), hstore_fetchval(), hstore_out(), hstore_populate_record(), hstore_send(), hstore_skeys(), hstore_slice_to_array(), hstore_slice_to_hstore(), hstore_svals(), hstore_to_array_internal(), hstore_to_json(), hstore_to_json_loose(), hstoreFindKey(), hstorePairs(), insertStatEntry(), make_tsvector(), silly_cmp_tsvector(), ts_match_vq(), tsvector_concat(), tsvector_strip(), tsvectorin(), tsvectorout(), tsvectorrecv(), and tsvectorsend().
Definition at line 73 of file hstore_op.c.
References deconstruct_array(), hstoreUniquePairs(), i, Pairs::isnull, Pairs::key, Pairs::keylen, Pairs::needfree, palloc(), TEXTOID, Pairs::val, Pairs::vallen, VARDATA, and VARSIZE.
Referenced by hstore_delete_array(), hstore_exists_all(), hstore_exists_any(), and hstore_slice_to_hstore().
{ Datum *key_datums; bool *key_nulls; int key_count; Pairs *key_pairs; int bufsiz; int i, j; deconstruct_array(a, TEXTOID, -1, false, 'i', &key_datums, &key_nulls, &key_count); if (key_count == 0) { *npairs = 0; return NULL; } key_pairs = palloc(sizeof(Pairs) * key_count); for (i = 0, j = 0; i < key_count; i++) { if (!key_nulls[i]) { key_pairs[j].key = VARDATA(key_datums[i]); key_pairs[j].keylen = VARSIZE(key_datums[i]) - VARHDRSZ; key_pairs[j].val = NULL; key_pairs[j].vallen = 0; key_pairs[j].needfree = 0; key_pairs[j].isnull = 1; j++; } } *npairs = hstoreUniquePairs(key_pairs, j, &bufsiz); return key_pairs; }
size_t hstoreCheckKeyLen | ( | size_t | len | ) |
Definition at line 351 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().
{ if (len > HSTORE_MAX_KEY_LEN) ereport(ERROR, (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION), errmsg("string too long for hstore key"))); return len; }
size_t hstoreCheckValLen | ( | size_t | len | ) |
Definition at line 361 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().
{ if (len > HSTORE_MAX_VALUE_LEN) ereport(ERROR, (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION), errmsg("string too long for hstore value"))); return len; }
int hstoreFindKey | ( | HStore * | hs, | |
int * | lowbound, | |||
char * | key, | |||
int | keylen | |||
) |
Definition at line 36 of file hstore_op.c.
References ARRPTR, HS_COUNT, HS_KEY, HS_KEYLEN, memcmp(), 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().
{ HEntry *entries = ARRPTR(hs); int stopLow = lowbound ? *lowbound : 0; int stopHigh = HS_COUNT(hs); int stopMiddle; char *base = STRPTR(hs); while (stopLow < stopHigh) { int difference; stopMiddle = stopLow + (stopHigh - stopLow) / 2; if (HS_KEYLEN(entries, stopMiddle) == keylen) difference = memcmp(HS_KEY(entries, base, stopMiddle), key, keylen); else difference = (HS_KEYLEN(entries, stopMiddle) > keylen) ? 1 : -1; if (difference == 0) { if (lowbound) *lowbound = stopMiddle + 1; return stopMiddle; } else if (difference < 0) stopLow = stopMiddle + 1; else stopHigh = stopMiddle; } if (lowbound) *lowbound = stopLow; return -1; }
Definition at line 372 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(), hstore_recv(), and hstore_slice_to_hstore().
{ HStore *out; HEntry *entry; char *ptr; char *buf; int32 len; int32 i; len = CALCDATASIZE(pcount, buflen); out = palloc(len); SET_VARSIZE(out, len); HS_SETCOUNT(out, pcount); if (pcount == 0) return out; entry = ARRPTR(out); buf = ptr = STRPTR(out); for (i = 0; i < pcount; i++) HS_ADDITEM(entry, buf, ptr, pairs[i]); HS_FINALIZE(out, pcount, buf, ptr); return out; }
Definition at line 309 of file hstore_io.c.
References comparePairs(), Pairs::isnull, Pairs::key, Pairs::keylen, memcmp(), Pairs::needfree, pfree(), qsort, Pairs::val, and Pairs::vallen.
Referenced by hstore_from_array(), hstore_from_arrays(), hstore_from_record(), hstore_in(), hstore_recv(), and hstoreArrayToPairs().
{ Pairs *ptr, *res; *buflen = 0; if (l < 2) { if (l == 1) *buflen = a->keylen + ((a->isnull) ? 0 : a->vallen); return l; } qsort((void *) a, l, sizeof(Pairs), comparePairs); ptr = a + 1; res = a; while (ptr - a < l) { if (ptr->keylen == res->keylen && memcmp(ptr->key, res->key, res->keylen) == 0) { if (ptr->needfree) { pfree(ptr->key); pfree(ptr->val); } } else { *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen); res++; memcpy(res, ptr, sizeof(Pairs)); } ptr++; } *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen); return res + 1 - a; }
Definition at line 236 of file hstore_compat.c.
References ARRPTR, DatumGetPointer, elog, HEntry::entry, ERROR, 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.
{ HStore *hs = (HStore *) PG_DETOAST_DATUM(orig); int valid_new; int valid_old; bool writable; /* Return immediately if no conversion needed */ if ((hs->size_ & HS_FLAG_NEWVERSION) || hs->size_ == 0 || (VARSIZE(hs) < 32768 && HSE_ISFIRST((ARRPTR(hs)[0])))) return hs; valid_new = hstoreValidNewFormat(hs); valid_old = hstoreValidOldFormat(hs); /* Do we have a writable copy? */ writable = ((void *) hs != (void *) DatumGetPointer(orig)); if (!valid_old || hs->size_ == 0) { if (valid_new) { /* * force the "new version" flag and the correct varlena length, * but only if we have a writable copy already (which we almost * always will, since short new-format values won't come through * here) */ if (writable) { HS_SETCOUNT(hs, HS_COUNT(hs)); HS_FIXSIZE(hs, HS_COUNT(hs)); } return hs; } else { elog(ERROR, "invalid hstore value found"); } } /* * this is the tricky edge case. It is only possible in some quite extreme * cases (the hstore must have had a lot of wasted padding space at the * end). But the only way a "new" hstore value could get here is if we're * upgrading in place from a pre-release version of hstore-new (NOT * contrib/hstore), so we work off the following assumptions: 1. If you're * moving from old contrib/hstore to hstore-new, you're required to fix up * any potential conflicts first, e.g. by running ALTER TABLE ... USING * col::text::hstore; on all hstore columns before upgrading. 2. If you're * moving from old contrib/hstore to new contrib/hstore, then "new" values * are impossible here 3. If you're moving from pre-release hstore-new to * hstore-new, then "old" values are impossible here 4. If you're moving * from pre-release hstore-new to new contrib/hstore, you're not doing so * as an in-place upgrade, so there is no issue So the upshot of all this * is that we can treat all the edge cases as "new" if we're being built * as hstore-new, and "old" if we're being built as contrib/hstore. * * XXX the WARNING can probably be downgraded to DEBUG1 once this has been * beta-tested. But for now, it would be very useful to know if anyone can * actually reach this case in a non-contrived setting. */ if (valid_new) { #if HSTORE_IS_HSTORE_NEW elog(WARNING, "ambiguous hstore value resolved as hstore-new"); /* * force the "new version" flag and the correct varlena length, but * only if we have a writable copy already (which we almost always * will, since short new-format values won't come through here) */ if (writable) { HS_SETCOUNT(hs, HS_COUNT(hs)); HS_FIXSIZE(hs, HS_COUNT(hs)); } return hs; #else elog(WARNING, "ambiguous hstore value resolved as hstore-old"); #endif } /* * must have an old-style value. Overwrite it in place as a new-style one, * making sure we have a writable copy first. */ if (!writable) hs = (HStore *) PG_DETOAST_DATUM_COPY(orig); { int count = hs->size_; HEntry *new_entries = ARRPTR(hs); HOldEntry *old_entries = (HOldEntry *) ARRPTR(hs); int i; for (i = 0; i < count; ++i) { uint32 pos = old_entries[i].pos; uint32 keylen = old_entries[i].keylen; uint32 vallen = old_entries[i].vallen; bool isnull = old_entries[i].valisnull; if (isnull) vallen = 0; new_entries[2 * i].entry = (pos + keylen) & HENTRY_POSMASK; new_entries[2 * i + 1].entry = (((pos + keylen + vallen) & HENTRY_POSMASK) | ((isnull) ? HENTRY_ISNULL : 0)); } if (count) new_entries[0].entry |= HENTRY_ISFIRST; HS_SETCOUNT(hs, count); HS_FIXSIZE(hs, count); } return hs; }