diff options
Diffstat (limited to 'contrib/hstore')
| -rw-r--r-- | contrib/hstore/hstore.h | 57 | ||||
| -rw-r--r-- | contrib/hstore/hstore_gist.c | 376 | ||||
| -rw-r--r-- | contrib/hstore/hstore_io.c | 533 | ||||
| -rw-r--r-- | contrib/hstore/hstore_op.c | 707 |
4 files changed, 950 insertions, 723 deletions
diff --git a/contrib/hstore/hstore.h b/contrib/hstore/hstore.h index 5fb5999610..20ae203416 100644 --- a/contrib/hstore/hstore.h +++ b/contrib/hstore/hstore.h @@ -11,39 +11,42 @@ #include "storage/bufpage.h" -typedef struct { - uint16 keylen; - uint16 vallen; - uint32 - valisnull:1, - pos:31; -} HEntry; - - -typedef struct { - int4 len; - int4 size; - char data[1]; -} HStore; +typedef struct +{ + uint16 keylen; + uint16 vallen; + uint32 + valisnull:1, + pos:31; +} HEntry; + + +typedef struct +{ + int4 len; + int4 size; + char data[1]; +} HStore; #define HSHRDSIZE (2*sizeof(int4)) #define CALCDATASIZE(x, lenstr) ( (x) * sizeof(HEntry) + HSHRDSIZE + (lenstr) ) -#define ARRPTR(x) ( (HEntry*) ( (char*)(x) + HSHRDSIZE ) ) -#define STRPTR(x) ( (char*)(x) + HSHRDSIZE + ( sizeof(HEntry) * ((HStore*)x)->size ) ) +#define ARRPTR(x) ( (HEntry*) ( (char*)(x) + HSHRDSIZE ) ) +#define STRPTR(x) ( (char*)(x) + HSHRDSIZE + ( sizeof(HEntry) * ((HStore*)x)->size ) ) -#define PG_GETARG_HS(x) ((HStore*)PG_DETOAST_DATUM(PG_GETARG_DATUM(x))) +#define PG_GETARG_HS(x) ((HStore*)PG_DETOAST_DATUM(PG_GETARG_DATUM(x))) -typedef struct { - char *key; - char *val; - uint16 keylen; - uint16 vallen; - bool isnull; - bool needfree; -} Pairs; +typedef struct +{ + char *key; + char *val; + uint16 keylen; + uint16 vallen; + bool isnull; + bool needfree; +} Pairs; -int comparePairs(const void *a, const void *b); -int uniquePairs(Pairs * a, int4 l, int4 *buflen); +int comparePairs(const void *a, const void *b); +int uniquePairs(Pairs * a, int4 l, int4 *buflen); #endif diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c index f1c8738266..4220a5541d 100644 --- a/contrib/hstore/hstore_gist.c +++ b/contrib/hstore/hstore_gist.c @@ -7,8 +7,8 @@ /* bigint defines */ #define BITBYTE 8 -#define SIGLENINT 4 /* >122 => key will toast, so very slow!!! */ -#define SIGLEN ( sizeof(int)*SIGLENINT ) +#define SIGLENINT 4 /* >122 => key will toast, so very slow!!! */ +#define SIGLEN ( sizeof(int)*SIGLENINT ) #define SIGLENBIT (SIGLEN*BITBYTE) typedef char BITVEC[SIGLEN]; @@ -36,22 +36,23 @@ typedef char *BITVECP; #define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT) #define HASH(sign, val) SETBIT((sign), HASHVAL(val)) -typedef struct { - int4 len; - int4 flag; - char data[1]; -} GISTTYPE; +typedef struct +{ + int4 len; + int4 flag; + char data[1]; +} GISTTYPE; -#define ALLISTRUE 0x04 +#define ALLISTRUE 0x04 -#define ISALLTRUE(x) ( ((GISTTYPE*)x)->flag & ALLISTRUE ) +#define ISALLTRUE(x) ( ((GISTTYPE*)x)->flag & ALLISTRUE ) -#define GTHDRSIZE ( sizeof(int4)*2 ) +#define GTHDRSIZE ( sizeof(int4)*2 ) #define CALCGTSIZE(flag) ( GTHDRSIZE+(((flag) & ALLISTRUE) ? 0 : SIGLEN) ) - -#define GETSIGN(x) ( (BITVECP)( (char*)x+GTHDRSIZE ) ) -#define SUMBIT(val) ( \ +#define GETSIGN(x) ( (BITVECP)( (char*)x+GTHDRSIZE ) ) + +#define SUMBIT(val) ( \ GETBITBYTE((val),0) + \ GETBITBYTE((val),1) + \ GETBITBYTE((val),2) + \ @@ -67,20 +68,22 @@ typedef struct { #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) ) PG_FUNCTION_INFO_V1(ghstore_in); -Datum ghstore_in(PG_FUNCTION_ARGS); +Datum ghstore_in(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(ghstore_out); -Datum ghstore_out(PG_FUNCTION_ARGS); - +Datum ghstore_out(PG_FUNCTION_ARGS); + Datum -ghstore_in(PG_FUNCTION_ARGS) { +ghstore_in(PG_FUNCTION_ARGS) +{ elog(ERROR, "Not implemented"); PG_RETURN_DATUM(0); } Datum -ghstore_out(PG_FUNCTION_ARGS) { +ghstore_out(PG_FUNCTION_ARGS) +{ elog(ERROR, "Not implemented"); PG_RETURN_DATUM(0); } @@ -93,36 +96,41 @@ PG_FUNCTION_INFO_V1(ghstore_picksplit); PG_FUNCTION_INFO_V1(ghstore_union); PG_FUNCTION_INFO_V1(ghstore_same); -Datum ghstore_consistent(PG_FUNCTION_ARGS); -Datum ghstore_compress(PG_FUNCTION_ARGS); -Datum ghstore_decompress(PG_FUNCTION_ARGS); -Datum ghstore_penalty(PG_FUNCTION_ARGS); -Datum ghstore_picksplit(PG_FUNCTION_ARGS); -Datum ghstore_union(PG_FUNCTION_ARGS); -Datum ghstore_same(PG_FUNCTION_ARGS); +Datum ghstore_consistent(PG_FUNCTION_ARGS); +Datum ghstore_compress(PG_FUNCTION_ARGS); +Datum ghstore_decompress(PG_FUNCTION_ARGS); +Datum ghstore_penalty(PG_FUNCTION_ARGS); +Datum ghstore_picksplit(PG_FUNCTION_ARGS); +Datum ghstore_union(PG_FUNCTION_ARGS); +Datum ghstore_same(PG_FUNCTION_ARGS); Datum -ghstore_compress(PG_FUNCTION_ARGS) { +ghstore_compress(PG_FUNCTION_ARGS) +{ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *retval = entry; - - if (entry->leafkey) { - GISTTYPE *res = (GISTTYPE*)palloc(CALCGTSIZE(0)); - HStore *toastedval = (HStore *) DatumGetPointer(entry->key); - HStore *val = (HStore *) DatumGetPointer(PG_DETOAST_DATUM(entry->key)); - HEntry *ptr = ARRPTR(val); - char *words = STRPTR(val); - - memset(res,0,CALCGTSIZE(0)); - res->len=CALCGTSIZE(0); - - while(ptr-ARRPTR(val) < val->size) { - int h; - h = crc32_sz((char*)(words+ptr->pos), ptr->keylen); - HASH( GETSIGN(res), h); - if ( !ptr->valisnull ) { - h = crc32_sz((char *)(words+ptr->pos+ptr->keylen), ptr->vallen); - HASH( GETSIGN(res), h); + + if (entry->leafkey) + { + GISTTYPE *res = (GISTTYPE *) palloc(CALCGTSIZE(0)); + HStore *toastedval = (HStore *) DatumGetPointer(entry->key); + HStore *val = (HStore *) DatumGetPointer(PG_DETOAST_DATUM(entry->key)); + HEntry *ptr = ARRPTR(val); + char *words = STRPTR(val); + + memset(res, 0, CALCGTSIZE(0)); + res->len = CALCGTSIZE(0); + + while (ptr - ARRPTR(val) < val->size) + { + int h; + + h = crc32_sz((char *) (words + ptr->pos), ptr->keylen); + HASH(GETSIGN(res), h); + if (!ptr->valisnull) + { + h = crc32_sz((char *) (words + ptr->pos + ptr->keylen), ptr->vallen); + HASH(GETSIGN(res), h); } ptr++; } @@ -135,14 +143,16 @@ ghstore_compress(PG_FUNCTION_ARGS) { entry->rel, entry->page, entry->offset, FALSE); - } else if ( !ISALLTRUE(DatumGetPointer(entry->key)) ) { - int4 i; + } + else if (!ISALLTRUE(DatumGetPointer(entry->key))) + { + int4 i; GISTTYPE *res; - BITVECP sign = GETSIGN(DatumGetPointer(entry->key)); - + BITVECP sign = GETSIGN(DatumGetPointer(entry->key)); + LOOPBYTE( - if ((sign[i] & 0xff) != 0xff) - PG_RETURN_POINTER(retval); + if ((sign[i] & 0xff) != 0xff) + PG_RETURN_POINTER(retval); ); res = (GISTTYPE *) palloc(CALCGTSIZE(ALLISTRUE)); @@ -152,7 +162,7 @@ ghstore_compress(PG_FUNCTION_ARGS) { retval = (GISTENTRY *) palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(res), entry->rel, entry->page, - entry->offset, + entry->offset, FALSE); } @@ -160,15 +170,17 @@ ghstore_compress(PG_FUNCTION_ARGS) { } Datum -ghstore_decompress(PG_FUNCTION_ARGS) { +ghstore_decompress(PG_FUNCTION_ARGS) +{ PG_RETURN_DATUM(PG_GETARG_DATUM(0)); } Datum -ghstore_same(PG_FUNCTION_ARGS) { +ghstore_same(PG_FUNCTION_ARGS) +{ GISTTYPE *a = (GISTTYPE *) PG_GETARG_POINTER(0); GISTTYPE *b = (GISTTYPE *) PG_GETARG_POINTER(1); - bool *result = (bool *) PG_GETARG_POINTER(2); + bool *result = (bool *) PG_GETARG_POINTER(2); if (ISALLTRUE(a) && ISALLTRUE(b)) *result = true; @@ -176,83 +188,97 @@ ghstore_same(PG_FUNCTION_ARGS) { *result = false; else if (ISALLTRUE(b)) *result = false; - else { - int4 i; - BITVECP sa = GETSIGN(a), - sb = GETSIGN(b); + else + { + int4 i; + BITVECP sa = GETSIGN(a), + sb = GETSIGN(b); + *result = true; LOOPBYTE( - if (sa[i] != sb[i]) { - *result = false; - break; - } + if (sa[i] != sb[i]) + { + *result = false; + break; + } ); } PG_RETURN_POINTER(result); } static int4 -sizebitvec(BITVECP sign) { - int4 size = 0, i; +sizebitvec(BITVECP sign) +{ + int4 size = 0, + i; + LOOPBYTE( - size += SUMBIT(sign); - sign = (BITVECP) (((char *) sign) + 1); + size += SUMBIT(sign); + sign = (BITVECP) (((char *) sign) + 1); ); return size; } - + static int -hemdistsign(BITVECP a, BITVECP b) { - int i,dist=0; +hemdistsign(BITVECP a, BITVECP b) +{ + int i, + dist = 0; LOOPBIT( - if ( GETBIT(a,i) != GETBIT(b,i) ) + if (GETBIT(a, i) != GETBIT(b, i)) dist++; ); return dist; } static int -hemdist(GISTTYPE *a, GISTTYPE *b) { - if ( ISALLTRUE(a) ) { +hemdist(GISTTYPE * a, GISTTYPE * b) +{ + if (ISALLTRUE(a)) + { if (ISALLTRUE(b)) return 0; else - return SIGLENBIT-sizebitvec(GETSIGN(b)); - } else if (ISALLTRUE(b)) - return SIGLENBIT-sizebitvec(GETSIGN(a)); + return SIGLENBIT - sizebitvec(GETSIGN(b)); + } + else if (ISALLTRUE(b)) + return SIGLENBIT - sizebitvec(GETSIGN(a)); - return hemdistsign( GETSIGN(a), GETSIGN(b) ); + return hemdistsign(GETSIGN(a), GETSIGN(b)); } static int4 unionkey(BITVECP sbase, GISTTYPE * add) { - int4 i; - BITVECP sadd = GETSIGN(add); + int4 i; + BITVECP sadd = GETSIGN(add); if (ISALLTRUE(add)) return 1; LOOPBYTE( - sbase[i] |= sadd[i]; + sbase[i] |= sadd[i]; ); return 0; } Datum -ghstore_union(PG_FUNCTION_ARGS) { - GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); - int4 len = entryvec->n; - - int *size = (int *) PG_GETARG_POINTER(1); - BITVEC base; - int4 i; - int4 flag = 0; +ghstore_union(PG_FUNCTION_ARGS) +{ + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); + int4 len = entryvec->n; + + int *size = (int *) PG_GETARG_POINTER(1); + BITVEC base; + int4 i; + int4 flag = 0; GISTTYPE *result; MemSet((void *) base, 0, sizeof(BITVEC)); - for (i = 0; i < len; i++) { - if (unionkey(base, GETENTRY(entryvec, i))) { + for (i = 0; i < len; i++) + { + if (unionkey(base, GETENTRY(entryvec, i))) + { flag = ALLISTRUE; break; } @@ -269,64 +295,72 @@ ghstore_union(PG_FUNCTION_ARGS) { } Datum -ghstore_penalty(PG_FUNCTION_ARGS) { +ghstore_penalty(PG_FUNCTION_ARGS) +{ GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */ GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); - float *penalty = (float *) PG_GETARG_POINTER(2); + float *penalty = (float *) PG_GETARG_POINTER(2); GISTTYPE *origval = (GISTTYPE *) DatumGetPointer(origentry->key); GISTTYPE *newval = (GISTTYPE *) DatumGetPointer(newentry->key); - *penalty=hemdist(origval,newval); + *penalty = hemdist(origval, newval); PG_RETURN_POINTER(penalty); } -typedef struct { +typedef struct +{ OffsetNumber pos; - int4 cost; -} SPLITCOST; + int4 cost; +} SPLITCOST; static int -comparecost(const void *a, const void *b) { +comparecost(const void *a, const void *b) +{ return ((SPLITCOST *) a)->cost - ((SPLITCOST *) b)->cost; } Datum -ghstore_picksplit(PG_FUNCTION_ARGS) { - GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); +ghstore_picksplit(PG_FUNCTION_ARGS) +{ + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); OffsetNumber maxoff = entryvec->n - 2; GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); OffsetNumber k, j; - GISTTYPE *datum_l, + GISTTYPE *datum_l, *datum_r; - BITVECP union_l, + BITVECP union_l, union_r; - int4 size_alpha, size_beta; - int4 size_waste, + int4 size_alpha, + size_beta; + int4 size_waste, waste = -1; - int4 nbytes; + int4 nbytes; OffsetNumber seed_1 = 0, seed_2 = 0; OffsetNumber *left, *right; - BITVECP ptr; - int i; + BITVECP ptr; + int i; SPLITCOST *costvector; - GISTTYPE *_k, + GISTTYPE *_k, *_j; nbytes = (maxoff + 2) * sizeof(OffsetNumber); v->spl_left = (OffsetNumber *) palloc(nbytes); v->spl_right = (OffsetNumber *) palloc(nbytes); - for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) { + for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) + { _k = GETENTRY(entryvec, k); - for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) { - size_waste=hemdist(_k, GETENTRY(entryvec, j)); - if (size_waste > waste ) { + for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) + { + size_waste = hemdist(_k, GETENTRY(entryvec, j)); + if (size_waste > waste) + { waste = size_waste; seed_1 = k; seed_2 = j; @@ -346,26 +380,32 @@ ghstore_picksplit(PG_FUNCTION_ARGS) { } /* form initial .. */ - if (ISALLTRUE(GETENTRY(entryvec, seed_1))) { + if (ISALLTRUE(GETENTRY(entryvec, seed_1))) + { datum_l = (GISTTYPE *) palloc(GTHDRSIZE); datum_l->len = GTHDRSIZE; datum_l->flag = ALLISTRUE; - } else { + } + else + { datum_l = (GISTTYPE *) palloc(GTHDRSIZE + SIGLEN); datum_l->len = GTHDRSIZE + SIGLEN; datum_l->flag = 0; memcpy((void *) GETSIGN(datum_l), (void *) GETSIGN(GETENTRY(entryvec, seed_1)), sizeof(BITVEC)) -; + ; } - if (ISALLTRUE(GETENTRY(entryvec, seed_2))) { + if (ISALLTRUE(GETENTRY(entryvec, seed_2))) + { datum_r = (GISTTYPE *) palloc(GTHDRSIZE); datum_r->len = GTHDRSIZE; datum_r->flag = ALLISTRUE; - } else { + } + else + { datum_r = (GISTTYPE *) palloc(GTHDRSIZE + SIGLEN); datum_r->len = GTHDRSIZE + SIGLEN; datum_r->flag = 0; - memcpy((void *) GETSIGN(datum_r), (void *) GETSIGN(GETENTRY(entryvec, seed_2)), sizeof(BITVEC)) ; + memcpy((void *) GETSIGN(datum_r), (void *) GETSIGN(GETENTRY(entryvec, seed_2)), sizeof(BITVEC)); } maxoff = OffsetNumberNext(maxoff); @@ -375,50 +415,63 @@ ghstore_picksplit(PG_FUNCTION_ARGS) { { costvector[j - 1].pos = j; _j = GETENTRY(entryvec, j); - size_alpha = hemdist(datum_l,_j); - size_beta = hemdist(datum_r,_j); + size_alpha = hemdist(datum_l, _j); + size_beta = hemdist(datum_r, _j); costvector[j - 1].cost = abs(size_alpha - size_beta); } qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost); - union_l=GETSIGN(datum_l); - union_r=GETSIGN(datum_r); + union_l = GETSIGN(datum_l); + union_r = GETSIGN(datum_r); - for (k = 0; k < maxoff; k++) { + for (k = 0; k < maxoff; k++) + { j = costvector[k].pos; - if (j == seed_1) { + if (j == seed_1) + { *left++ = j; v->spl_nleft++; continue; - } else if (j == seed_2) { + } + else if (j == seed_2) + { *right++ = j; v->spl_nright++; continue; } _j = GETENTRY(entryvec, j); - size_alpha = hemdist(datum_l,_j); - size_beta = hemdist(datum_r,_j); + size_alpha = hemdist(datum_l, _j); + size_beta = hemdist(datum_r, _j); - if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.0001)) { - if (ISALLTRUE(datum_l) || ISALLTRUE(_j) ) { + if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.0001)) + { + if (ISALLTRUE(datum_l) || ISALLTRUE(_j)) + { if (!ISALLTRUE(datum_l)) MemSet((void *) union_l, 0xff, sizeof(BITVEC)); - } else { - ptr=GETSIGN(_j); + } + else + { + ptr = GETSIGN(_j); LOOPBYTE( - union_l[i] |= ptr[i]; + union_l[i] |= ptr[i]; ); } *left++ = j; v->spl_nleft++; - } else { - if (ISALLTRUE(datum_r) || ISALLTRUE(_j) ) { + } + else + { + if (ISALLTRUE(datum_r) || ISALLTRUE(_j)) + { if (!ISALLTRUE(datum_r)) MemSet((void *) union_r, 0xff, sizeof(BITVEC)); - } else { - ptr=GETSIGN(_j); + } + else + { + ptr = GETSIGN(_j); LOOPBYTE( - union_r[i] |= ptr[i]; + union_r[i] |= ptr[i]; ); } *right++ = j; @@ -436,36 +489,41 @@ ghstore_picksplit(PG_FUNCTION_ARGS) { } -Datum -ghstore_consistent(PG_FUNCTION_ARGS) { - GISTTYPE *entry = (GISTTYPE*) DatumGetPointer( ((GISTENTRY *) PG_GETARG_POINTER(0))->key ); - HStore *query=PG_GETARG_HS(1); - bool res=true; - HEntry *qe = ARRPTR(query); - char *qv = STRPTR(query); - BITVECP sign; - - if ( ISALLTRUE(entry) ) { - PG_FREE_IF_COPY(query,1); +Datum +ghstore_consistent(PG_FUNCTION_ARGS) +{ + GISTTYPE *entry = (GISTTYPE *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key); + HStore *query = PG_GETARG_HS(1); + bool res = true; + HEntry *qe = ARRPTR(query); + char *qv = STRPTR(query); + BITVECP sign; + + if (ISALLTRUE(entry)) + { + PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(true); } - sign=GETSIGN(entry); - while(res && qe-ARRPTR(query) < query->size) { - int crc = crc32_sz((char *)(qv + qe->pos), qe->keylen); - if (GETBIT(sign,HASHVAL(crc))) { - if ( !qe->valisnull ) { - crc = crc32_sz((char *)(qv + qe->pos + qe->keylen), qe->vallen); - if ( !GETBIT(sign,HASHVAL(crc)) ) - res=false; + sign = GETSIGN(entry); + while (res && qe - ARRPTR(query) < query->size) + { + int crc = crc32_sz((char *) (qv + qe->pos), qe->keylen); + + if (GETBIT(sign, HASHVAL(crc))) + { + if (!qe->valisnull) + { + crc = crc32_sz((char *) (qv + qe->pos + qe->keylen), qe->vallen); + if (!GETBIT(sign, HASHVAL(crc))) + res = false; } - } else - res=false; + } + else + res = false; qe++; } - PG_FREE_IF_COPY(query,1); + PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(res); } - - diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c index 051a411a99..e01cb4e759 100644 --- a/contrib/hstore/hstore_io.c +++ b/contrib/hstore/hstore_io.c @@ -3,304 +3,396 @@ PG_MODULE_MAGIC; -typedef struct { - char *begin; - char *ptr; - char *cur; - char *word; - int wordlen; - - Pairs *pairs; - int pcur; - int plen; -} HSParser; +typedef struct +{ + char *begin; + char *ptr; + char *cur; + char *word; + int wordlen; + + Pairs *pairs; + int pcur; + int plen; +} HSParser; #define RESIZEPRSBUF \ do { \ - if ( state->cur - state->word + 1 >= state->wordlen ) \ - { \ - int4 clen = state->cur - state->word; \ - state->wordlen *= 2; \ - state->word = (char*)repalloc( (void*)state->word, state->wordlen ); \ - state->cur = state->word + clen; \ - } \ + if ( state->cur - state->word + 1 >= state->wordlen ) \ + { \ + int4 clen = state->cur - state->word; \ + state->wordlen *= 2; \ + state->word = (char*)repalloc( (void*)state->word, state->wordlen ); \ + state->cur = state->word + clen; \ + } \ } while (0) -#define GV_WAITVAL 0 -#define GV_INVAL 1 -#define GV_INESCVAL 2 -#define GV_WAITESCIN 3 -#define GV_WAITESCESCIN 4 +#define GV_WAITVAL 0 +#define GV_INVAL 1 +#define GV_INESCVAL 2 +#define GV_WAITESCIN 3 +#define GV_WAITESCESCIN 4 static bool -get_val( HSParser *state, bool ignoreeq, bool *escaped ) { - int st = GV_WAITVAL; - state->wordlen=32; - state->cur = state->word = palloc( state->wordlen ); - *escaped=false; - - while(1) { - if ( st == GV_WAITVAL ) { - if ( *(state->ptr) == '"' ) { - *escaped=true; +get_val(HSParser * state, bool ignoreeq, bool *escaped) +{ + int st = GV_WAITVAL; + + state->wordlen = 32; + state->cur = state->word = palloc(state->wordlen); + *escaped = false; + + while (1) + { + if (st == GV_WAITVAL) + { + if (*(state->ptr) == '"') + { + *escaped = true; st = GV_INESCVAL; - } else if ( *(state->ptr) == '\0' ) { + } + else if (*(state->ptr) == '\0') + { return false; - } else if ( *(state->ptr) == '=' && !ignoreeq ) { - elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin)); - } else if ( *(state->ptr) == '\\' ) { + } + else if (*(state->ptr) == '=' && !ignoreeq) + { + elog(ERROR, "Syntax error near '%c' at postion %d", *(state->ptr), (int4) (state->ptr - state->begin)); + } + else if (*(state->ptr) == '\\') + { st = GV_WAITESCIN; - } else if ( !isspace((unsigned char) *(state->ptr)) ) { + } + else if (!isspace((unsigned char) *(state->ptr))) + { *(state->cur) = *(state->ptr); state->cur++; st = GV_INVAL; } - } else if ( st == GV_INVAL ) { - if ( *(state->ptr) == '\\' ) { + } + else if (st == GV_INVAL) + { + if (*(state->ptr) == '\\') + { st = GV_WAITESCIN; - } else if ( *(state->ptr) == '=' && !ignoreeq ) { + } + else if (*(state->ptr) == '=' && !ignoreeq) + { state->ptr--; return true; - } else if ( *(state->ptr) == ',' && ignoreeq ) { + } + else if (*(state->ptr) == ',' && ignoreeq) + { state->ptr--; return true; - } else if ( isspace((unsigned char) *(state->ptr)) ) { + } + else if (isspace((unsigned char) *(state->ptr))) + { return true; - } else if ( *(state->ptr) == '\0' ) { + } + else if (*(state->ptr) == '\0') + { state->ptr--; return true; - } else { + } + else + { RESIZEPRSBUF; *(state->cur) = *(state->ptr); state->cur++; } - } else if ( st == GV_INESCVAL ) { - if ( *(state->ptr) == '\\' ) { + } + else if (st == GV_INESCVAL) + { + if (*(state->ptr) == '\\') + { st = GV_WAITESCESCIN; - } else if ( *(state->ptr) == '"' ) { + } + else if (*(state->ptr) == '"') + { return true; - } else if ( *(state->ptr) == '\0' ) { - elog(ERROR,"Unexpected end of string"); - } else { + } + else if (*(state->ptr) == '\0') + { + elog(ERROR, "Unexpected end of string"); + } + else + { RESIZEPRSBUF; *(state->cur) = *(state->ptr); state->cur++; } - } else if ( st == GV_WAITESCIN ) { - if ( *(state->ptr) == '\0' ) - elog(ERROR,"Unexpected end of string"); + } + else if (st == GV_WAITESCIN) + { + if (*(state->ptr) == '\0') + elog(ERROR, "Unexpected end of string"); RESIZEPRSBUF; *(state->cur) = *(state->ptr); state->cur++; - st = GV_INVAL; - } else if ( st == GV_WAITESCESCIN ) { - if ( *(state->ptr) == '\0' ) - elog(ERROR,"Unexpected end of string"); + st = GV_INVAL; + } + else if (st == GV_WAITESCESCIN) + { + if (*(state->ptr) == '\0') + elog(ERROR, "Unexpected end of string"); RESIZEPRSBUF; *(state->cur) = *(state->ptr); state->cur++; st = GV_INESCVAL; - } else - elog(ERROR,"Unknown state %d at postion line %d in file '%s'", st, __LINE__, __FILE__); + } + else + elog(ERROR, "Unknown state %d at postion line %d in file '%s'", st, __LINE__, __FILE__); state->ptr++; - } + } return false; } #define WKEY 0 #define WVAL 1 -#define WEQ 2 -#define WGT 3 +#define WEQ 2 +#define WGT 3 #define WDEL 4 static void -parse_hstore( HSParser *state ) { - int st = WKEY; - bool escaped=false; - - state->plen=16; - state->pairs = (Pairs*)palloc( sizeof(Pairs) * state->plen ); - state->pcur=0; +parse_hstore(HSParser * state) +{ + int st = WKEY; + bool escaped = false; + + state->plen = 16; + state->pairs = (Pairs *) palloc(sizeof(Pairs) * state->plen); + state->pcur = 0; state->ptr = state->begin; - state->word=NULL; + state->word = NULL; - while(1) { - if (st == WKEY) { - if ( !get_val(state, false, &escaped) ) + while (1) + { + if (st == WKEY) + { + if (!get_val(state, false, &escaped)) return; - if ( state->pcur >= state->plen ) { + if (state->pcur >= state->plen) + { state->plen *= 2; - state->pairs = (Pairs*)repalloc( state->pairs, sizeof(Pairs) * state->plen ); + state->pairs = (Pairs *) repalloc(state->pairs, sizeof(Pairs) * state->plen); } - state->pairs[ state->pcur ].key = state->word; - state->pairs[ state->pcur ].keylen = state->cur - state->word; - state->pairs[ state->pcur ].val=NULL; - state->word=NULL; + state->pairs[state->pcur].key = state->word; + state->pairs[state->pcur].keylen = state->cur - state->word; + state->pairs[state->pcur].val = NULL; + state->word = NULL; st = WEQ; - } else if ( st == WEQ ) { - if ( *(state->ptr) == '=' ) { + } + else if (st == WEQ) + { + if (*(state->ptr) == '=') + { st = WGT; - } else if ( *(state->ptr) == '\0' ) { - elog(ERROR,"Unexpectd end of string"); - } else if (!isspace((unsigned char) *(state->ptr))) { - elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin)); } - } else if ( st == WGT ) { - if ( *(state->ptr) == '>' ) { + else if (*(state->ptr) == '\0') + { + elog(ERROR, "Unexpectd end of string"); + } + else if (!isspace((unsigned char) *(state->ptr))) + { + elog(ERROR, "Syntax error near '%c' at postion %d", *(state->ptr), (int4) (state->ptr - state->begin)); + } + } + else if (st == WGT) + { + if (*(state->ptr) == '>') + { st = WVAL; - } else if ( *(state->ptr) == '\0' ) { - elog(ERROR,"Unexpectd end of string"); - } else { - elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin)); } - } else if ( st == WVAL ) { - if ( !get_val(state, true, &escaped) ) - elog(ERROR,"Unexpected end of string"); - state->pairs[ state->pcur ].val = state->word; - state->pairs[ state->pcur ].vallen = state->cur - state->word; - state->pairs[ state->pcur ].isnull = false; - state->pairs[ state->pcur ].needfree = true; - if ( state->cur - state->word == 4 && !escaped) { + else if (*(state->ptr) == '\0') + { + elog(ERROR, "Unexpectd end of string"); + } + else + { + elog(ERROR, "Syntax error near '%c' at postion %d", *(state->ptr), (int4) (state->ptr - state->begin)); + } + } + else if (st == WVAL) + { + if (!get_val(state, true, &escaped)) + elog(ERROR, "Unexpected end of string"); + state->pairs[state->pcur].val = state->word; + state->pairs[state->pcur].vallen = state->cur - state->word; + state->pairs[state->pcur].isnull = false; + state->pairs[state->pcur].needfree = true; + if (state->cur - state->word == 4 && !escaped) + { state->word[4] = '\0'; - if ( 0==pg_strcasecmp(state->word, "null") ) - state->pairs[ state->pcur ].isnull=true; - } - state->word=NULL; + if (0 == pg_strcasecmp(state->word, "null")) + state->pairs[state->pcur].isnull = true; + } + state->word = NULL; state->pcur++; st = WDEL; - } else if ( st == WDEL ) { - if ( *(state->ptr) == ',' ) { + } + else if (st == WDEL) + { + if (*(state->ptr) == ',') + { st = WKEY; - } else if ( *(state->ptr) == '\0' ) { + } + else if (*(state->ptr) == '\0') + { return; - } else if (!isspace((unsigned char) *(state->ptr))) { - elog(ERROR,"Syntax error near '%c' at postion %d", *(state->ptr), (int4)(state->ptr-state->begin)); } - } else - elog(ERROR,"Unknown state %d at line %d in file '%s'", st, __LINE__, __FILE__); + else if (!isspace((unsigned char) *(state->ptr))) + { + elog(ERROR, "Syntax error near '%c' at postion %d", *(state->ptr), (int4) (state->ptr - state->begin)); + } + } + else + elog(ERROR, "Unknown state %d at line %d in file '%s'", st, __LINE__, __FILE__); state->ptr++; } -} +} int -comparePairs(const void *a, const void *b) { - if ( ((Pairs*)a)->keylen == ((Pairs*)b)->keylen ) { - int res = strncmp( - ((Pairs*)a)->key, - ((Pairs*)b)->key, - ((Pairs*)a)->keylen - ); - if ( res ) +comparePairs(const void *a, const void *b) +{ + if (((Pairs *) a)->keylen == ((Pairs *) b)->keylen) + { + int res = strncmp( + ((Pairs *) a)->key, + ((Pairs *) b)->key, + ((Pairs *) a)->keylen + ); + + if (res) return res; /* guarantee that neddfree willl be later */ - if ( ((Pairs*)b)->needfree == ((Pairs*)a)->needfree ) + if (((Pairs *) b)->needfree == ((Pairs *) a)->needfree) return 0; - else if ( ((Pairs*)a)->needfree ) + else if (((Pairs *) a)->needfree) return 1; else - return -1; + return -1; } - return ( ((Pairs*)a)->keylen > ((Pairs*)b)->keylen ) ? 1 : -1; + return (((Pairs *) a)->keylen > ((Pairs *) b)->keylen) ? 1 : -1; } int -uniquePairs(Pairs * a, int4 l, int4 *buflen) { - Pairs *ptr, *res; - - *buflen=0; - if ( l < 2 ) { - if ( l==1 ) - *buflen = a->keylen + ((a->isnull) ? 0 : a->vallen) ; +uniquePairs(Pairs * a, int4 l, int4 *buflen) +{ + 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 && strncmp( ptr->key, res->key, res->keylen )==0 ) { - if ( ptr->needfree ) { + ptr = a + 1; + res = a; + while (ptr - a < l) + { + if (ptr->keylen == res->keylen && strncmp(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); + } + else + { + *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen); res++; - memcpy(res,ptr,sizeof(Pairs)); + memcpy(res, ptr, sizeof(Pairs)); } ptr++; } - *buflen += res->keylen + (( res->isnull ) ? 0 : res->vallen); + *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen); return res + 1 - a; } static void -freeHSParse(HSParser *state) { - int i; - - if ( state->word ) pfree( state->word ); - for (i=0;i<state->pcur;i++) - if ( state->pairs[i].needfree ) { - if (state->pairs[i].key) pfree(state->pairs[i].key); - if (state->pairs[i].val) pfree(state->pairs[i].val); +freeHSParse(HSParser * state) +{ + int i; + + if (state->word) + pfree(state->word); + for (i = 0; i < state->pcur; i++) + if (state->pairs[i].needfree) + { + if (state->pairs[i].key) + pfree(state->pairs[i].key); + if (state->pairs[i].val) + pfree(state->pairs[i].val); } - pfree( state->pairs ); + pfree(state->pairs); } PG_FUNCTION_INFO_V1(hstore_in); -Datum hstore_in(PG_FUNCTION_ARGS); +Datum hstore_in(PG_FUNCTION_ARGS); Datum -hstore_in(PG_FUNCTION_ARGS) { - HSParser state; - int4 len,buflen,i; - HStore *out; - HEntry *entries; - char *ptr; - - state.begin = PG_GETARG_CSTRING(0); +hstore_in(PG_FUNCTION_ARGS) +{ + HSParser state; + int4 len, + buflen, + i; + HStore *out; + HEntry *entries; + char *ptr; + + state.begin = PG_GETARG_CSTRING(0); parse_hstore(&state); - if ( state.pcur == 0 ) { + if (state.pcur == 0) + { freeHSParse(&state); - len = CALCDATASIZE(0,0); + len = CALCDATASIZE(0, 0); out = palloc(len); - out->len=len; - out->size=0; + out->len = len; + out->size = 0; PG_RETURN_POINTER(out); } state.pcur = uniquePairs(state.pairs, state.pcur, &buflen); - len=CALCDATASIZE(state.pcur, buflen); + len = CALCDATASIZE(state.pcur, buflen); out = palloc(len); - out->len=len; - out->size=state.pcur; + out->len = len; + out->size = state.pcur; - entries=ARRPTR(out); + entries = ARRPTR(out); ptr = STRPTR(out); - for(i=0;i<out->size;i++) { + for (i = 0; i < out->size; i++) + { entries[i].keylen = state.pairs[i].keylen; entries[i].pos = ptr - STRPTR(out); memcpy(ptr, state.pairs[i].key, state.pairs[i].keylen); - ptr+=entries[i].keylen; + ptr += entries[i].keylen; entries[i].valisnull = state.pairs[i].isnull; - if ( entries[i].valisnull ) - entries[i].vallen=4; /* null */ - else { + if (entries[i].valisnull) + entries[i].vallen = 4; /* null */ + else + { entries[i].vallen = state.pairs[i].vallen; - memcpy(ptr, state.pairs[i].val,state.pairs[i].vallen); - ptr+=entries[i].vallen; + memcpy(ptr, state.pairs[i].val, state.pairs[i].vallen); + ptr += entries[i].vallen; } } @@ -308,63 +400,74 @@ hstore_in(PG_FUNCTION_ARGS) { PG_RETURN_POINTER(out); } -static char* -cpw(char *dst, char *src, int len) { - char *ptr = src; +static char * +cpw(char *dst, char *src, int len) +{ + char *ptr = src; - while(ptr-src<len) { - if ( *ptr == '"' || *ptr == '\\' ) - *dst++='\\'; + while (ptr - src < len) + { + if (*ptr == '"' || *ptr == '\\') + *dst++ = '\\'; *dst++ = *ptr++; } return dst; } PG_FUNCTION_INFO_V1(hstore_out); -Datum hstore_out(PG_FUNCTION_ARGS); +Datum hstore_out(PG_FUNCTION_ARGS); Datum -hstore_out(PG_FUNCTION_ARGS) { - HStore *in = PG_GETARG_HS(0); - int buflen,i; - char *out,*ptr; - char *base = STRPTR(in); - HEntry *entries = ARRPTR(in); - - if ( in->size==0 ) { - out=palloc(1); - *out='\0'; - PG_FREE_IF_COPY(in,0); +hstore_out(PG_FUNCTION_ARGS) +{ + HStore *in = PG_GETARG_HS(0); + int buflen, + i; + char *out, + *ptr; + char *base = STRPTR(in); + HEntry *entries = ARRPTR(in); + + if (in->size == 0) + { + out = palloc(1); + *out = '\0'; + PG_FREE_IF_COPY(in, 0); PG_RETURN_CSTRING(out); } - buflen = ( 4 /* " */ + 2 /* => */ + 2 /*, */ )*in->size + - 2 /* esc */ * ( in->len - CALCDATASIZE(in->size,0) ); - - out=ptr=palloc(buflen); - for(i=0;i<in->size;i++) { - *ptr++='"'; - ptr = cpw( ptr, base + entries[i].pos, entries[i].keylen ); - *ptr++='"'; - *ptr++='='; - *ptr++='>'; - if ( entries[i].valisnull ) { - *ptr++='N'; - *ptr++='U'; - *ptr++='L'; - *ptr++='L'; - } else { - *ptr++='"'; - ptr = cpw( ptr, base + entries[i].pos + entries[i].keylen, entries[i].vallen ); - *ptr++='"'; + buflen = (4 /* " */ + 2 /* => */ + 2 /* , */ ) * in->size + + 2 /* esc */ * (in->len - CALCDATASIZE(in->size, 0)); + + out = ptr = palloc(buflen); + for (i = 0; i < in->size; i++) + { + *ptr++ = '"'; + ptr = cpw(ptr, base + entries[i].pos, entries[i].keylen); + *ptr++ = '"'; + *ptr++ = '='; + *ptr++ = '>'; + if (entries[i].valisnull) + { + *ptr++ = 'N'; + *ptr++ = 'U'; + *ptr++ = 'L'; + *ptr++ = 'L'; + } + else + { + *ptr++ = '"'; + ptr = cpw(ptr, base + entries[i].pos + entries[i].keylen, entries[i].vallen); + *ptr++ = '"'; } - if ( i+1 != in->size ) { - *ptr++=','; - *ptr++=' '; + if (i + 1 != in->size) + { + *ptr++ = ','; + *ptr++ = ' '; } } - *ptr='\0'; + *ptr = '\0'; - PG_FREE_IF_COPY(in,0); + PG_FREE_IF_COPY(in, 0); PG_RETURN_CSTRING(out); } diff --git a/contrib/hstore/hstore_op.c b/contrib/hstore/hstore_op.c index 12f783cb25..971e93cf31 100644 --- a/contrib/hstore/hstore_op.c +++ b/contrib/hstore/hstore_op.c @@ -7,20 +7,22 @@ static HEntry * -findkey(HStore *hs, char *key, int keylen) { - HEntry *StopLow = ARRPTR(hs); - HEntry *StopHigh = StopLow + hs->size; - HEntry *StopMiddle; - int difference; - char *base = STRPTR(hs); - - while (StopLow < StopHigh) { +findkey(HStore * hs, char *key, int keylen) +{ + HEntry *StopLow = ARRPTR(hs); + HEntry *StopHigh = StopLow + hs->size; + HEntry *StopMiddle; + int difference; + char *base = STRPTR(hs); + + while (StopLow < StopHigh) + { StopMiddle = StopLow + (StopHigh - StopLow) / 2; - if ( StopMiddle->keylen == keylen ) - difference=strncmp(base+StopMiddle->pos, key, StopMiddle->keylen); + if (StopMiddle->keylen == keylen) + difference = strncmp(base + StopMiddle->pos, key, StopMiddle->keylen); else - difference=(StopMiddle->keylen > keylen) ? 1 : -1; + difference = (StopMiddle->keylen > keylen) ? 1 : -1; if (difference == 0) return StopMiddle; @@ -29,520 +31,583 @@ findkey(HStore *hs, char *key, int keylen) { else StopHigh = StopMiddle; } - + return NULL; } PG_FUNCTION_INFO_V1(fetchval); -Datum fetchval(PG_FUNCTION_ARGS); +Datum fetchval(PG_FUNCTION_ARGS); Datum -fetchval(PG_FUNCTION_ARGS) { - HStore *hs = PG_GETARG_HS(0); - text *key = PG_GETARG_TEXT_P(1); - HEntry *entry; - text *out; - - if ((entry=findkey(hs,VARDATA(key), VARSIZE(key)-VARHDRSZ))==NULL || entry->valisnull) { - PG_FREE_IF_COPY(hs,0); - PG_FREE_IF_COPY(key,1); +fetchval(PG_FUNCTION_ARGS) +{ + HStore *hs = PG_GETARG_HS(0); + text *key = PG_GETARG_TEXT_P(1); + HEntry *entry; + text *out; + + if ((entry = findkey(hs, VARDATA(key), VARSIZE(key) - VARHDRSZ)) == NULL || entry->valisnull) + { + PG_FREE_IF_COPY(hs, 0); + PG_FREE_IF_COPY(key, 1); PG_RETURN_NULL(); } - out=palloc(VARHDRSZ+entry->vallen); - memcpy(VARDATA(out),STRPTR(hs) + entry->pos + entry->keylen, entry->vallen); - VARATT_SIZEP(out) = VARHDRSZ+entry->vallen; + out = palloc(VARHDRSZ + entry->vallen); + memcpy(VARDATA(out), STRPTR(hs) + entry->pos + entry->keylen, entry->vallen); + VARATT_SIZEP(out) = VARHDRSZ + entry->vallen; - PG_FREE_IF_COPY(hs,0); - PG_FREE_IF_COPY(key,1); + PG_FREE_IF_COPY(hs, 0); + PG_FREE_IF_COPY(key, 1); PG_RETURN_POINTER(out); } PG_FUNCTION_INFO_V1(exists); -Datum exists(PG_FUNCTION_ARGS); +Datum exists(PG_FUNCTION_ARGS); Datum -exists(PG_FUNCTION_ARGS) { - HStore *hs = PG_GETARG_HS(0); - text *key = PG_GETARG_TEXT_P(1); - HEntry *entry; +exists(PG_FUNCTION_ARGS) +{ + HStore *hs = PG_GETARG_HS(0); + text *key = PG_GETARG_TEXT_P(1); + HEntry *entry; - entry=findkey(hs,VARDATA(key), VARSIZE(key)-VARHDRSZ); + entry = findkey(hs, VARDATA(key), VARSIZE(key) - VARHDRSZ); - PG_FREE_IF_COPY(hs,0); - PG_FREE_IF_COPY(key,1); + PG_FREE_IF_COPY(hs, 0); + PG_FREE_IF_COPY(key, 1); PG_RETURN_BOOL(entry); } PG_FUNCTION_INFO_V1(defined); -Datum defined(PG_FUNCTION_ARGS); +Datum defined(PG_FUNCTION_ARGS); Datum -defined(PG_FUNCTION_ARGS) { - HStore *hs = PG_GETARG_HS(0); - text *key = PG_GETARG_TEXT_P(1); - HEntry *entry; - bool res; +defined(PG_FUNCTION_ARGS) +{ + HStore *hs = PG_GETARG_HS(0); + text *key = PG_GETARG_TEXT_P(1); + HEntry *entry; + bool res; - entry=findkey(hs,VARDATA(key), VARSIZE(key)-VARHDRSZ); + entry = findkey(hs, VARDATA(key), VARSIZE(key) - VARHDRSZ); - res = ( entry && !entry->valisnull ) ? true : false; + res = (entry && !entry->valisnull) ? true : false; - PG_FREE_IF_COPY(hs,0); - PG_FREE_IF_COPY(key,1); + PG_FREE_IF_COPY(hs, 0); + PG_FREE_IF_COPY(key, 1); PG_RETURN_BOOL(res); } PG_FUNCTION_INFO_V1(delete); -Datum delete(PG_FUNCTION_ARGS); +Datum delete(PG_FUNCTION_ARGS); Datum -delete(PG_FUNCTION_ARGS) { - HStore *hs = PG_GETARG_HS(0); - text *key = PG_GETARG_TEXT_P(1); - HStore *out = palloc(hs->len); - char *ptrs, *ptrd; - HEntry *es, *ed; - - out->len=hs->len; - out->size=hs->size; /* temprorary! */ - - ptrs=STRPTR(hs); - es =ARRPTR(hs); - ptrd=STRPTR(out); - ed =ARRPTR(out); - - while( es - ARRPTR(hs) < hs->size ) { - if ( !(es->keylen == VARSIZE(key) - VARHDRSZ && strncmp(ptrs, VARDATA(key), es->keylen)==0) ) { - memcpy( ed, es, sizeof(HEntry) ); - memcpy( ptrd, ptrs, es->keylen + ( (es->valisnull) ? 0 : es->vallen ) ); +delete(PG_FUNCTION_ARGS) +{ + HStore *hs = PG_GETARG_HS(0); + text *key = PG_GETARG_TEXT_P(1); + HStore *out = palloc(hs->len); + char *ptrs, + *ptrd; + HEntry *es, + *ed; + + out->len = hs->len; + out->size = hs->size; /* temprorary! */ + + ptrs = STRPTR(hs); + es = ARRPTR(hs); + ptrd = STRPTR(out); + ed = ARRPTR(out); + + while (es - ARRPTR(hs) < hs->size) + { + if (!(es->keylen == VARSIZE(key) - VARHDRSZ && strncmp(ptrs, VARDATA(key), es->keylen) == 0)) + { + memcpy(ed, es, sizeof(HEntry)); + memcpy(ptrd, ptrs, es->keylen + ((es->valisnull) ? 0 : es->vallen)); ed->pos = ptrd - STRPTR(out); - ptrd += es->keylen + ( (es->valisnull) ? 0 : es->vallen ); + ptrd += es->keylen + ((es->valisnull) ? 0 : es->vallen); ed++; } - ptrs += es->keylen + ( (es->valisnull) ? 0 : es->vallen ); + ptrs += es->keylen + ((es->valisnull) ? 0 : es->vallen); es++; } - if ( ed - ARRPTR(out) != out->size ) { - int buflen=ptrd-STRPTR(out); + if (ed - ARRPTR(out) != out->size) + { + int buflen = ptrd - STRPTR(out); + ptrd = STRPTR(out); out->size = ed - ARRPTR(out); - memmove( STRPTR(out), ptrd, buflen); + memmove(STRPTR(out), ptrd, buflen); out->len = CALCDATASIZE(out->size, buflen); } - - PG_FREE_IF_COPY(hs,0); - PG_FREE_IF_COPY(key,1); + + PG_FREE_IF_COPY(hs, 0); + PG_FREE_IF_COPY(key, 1); PG_RETURN_POINTER(out); } PG_FUNCTION_INFO_V1(hs_concat); -Datum hs_concat(PG_FUNCTION_ARGS); +Datum hs_concat(PG_FUNCTION_ARGS); Datum -hs_concat(PG_FUNCTION_ARGS) { - HStore *s1 = PG_GETARG_HS(0); - HStore *s2 = PG_GETARG_HS(1); - HStore *out = palloc( s1->len + s2->len ); - char *ps1, *ps2, *pd; - HEntry *es1, *es2, *ed; +hs_concat(PG_FUNCTION_ARGS) +{ + HStore *s1 = PG_GETARG_HS(0); + HStore *s2 = PG_GETARG_HS(1); + HStore *out = palloc(s1->len + s2->len); + char *ps1, + *ps2, + *pd; + HEntry *es1, + *es2, + *ed; out->len = s1->len + s2->len; out->size = s1->size + s2->size; - ps1=STRPTR(s1); - ps2=STRPTR(s2); - pd=STRPTR(out); - es1=ARRPTR(s1); - es2=ARRPTR(s2); - ed=ARRPTR(out); - - while( es1 - ARRPTR(s1) < s1->size && es2 - ARRPTR(s2) < s2->size ) { - int difference; - if ( es1->keylen == es2->keylen ) - difference=strncmp(ps1, ps2, es1->keylen); + ps1 = STRPTR(s1); + ps2 = STRPTR(s2); + pd = STRPTR(out); + es1 = ARRPTR(s1); + es2 = ARRPTR(s2); + ed = ARRPTR(out); + + while (es1 - ARRPTR(s1) < s1->size && es2 - ARRPTR(s2) < s2->size) + { + int difference; + + if (es1->keylen == es2->keylen) + difference = strncmp(ps1, ps2, es1->keylen); else - difference=(es1->keylen > es2->keylen) ? 1 : -1; + difference = (es1->keylen > es2->keylen) ? 1 : -1; - if ( difference == 0 ) { - memcpy( ed, es2, sizeof(HEntry) ); - memcpy( pd, ps2, es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ) ); + if (difference == 0) + { + memcpy(ed, es2, sizeof(HEntry)); + memcpy(pd, ps2, es2->keylen + ((es2->valisnull) ? 0 : es2->vallen)); ed->pos = pd - STRPTR(out); - pd += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ); + pd += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen); ed++; - - ps1 += es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen ); + + ps1 += es1->keylen + ((es1->valisnull) ? 0 : es1->vallen); es1++; - ps2 += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ); + ps2 += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen); es2++; - } else if ( difference > 0 ) { - memcpy( ed, es2, sizeof(HEntry) ); - memcpy( pd, ps2, es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ) ); + } + else if (difference > 0) + { + memcpy(ed, es2, sizeof(HEntry)); + memcpy(pd, ps2, es2->keylen + ((es2->valisnull) ? 0 : es2->vallen)); ed->pos = pd - STRPTR(out); - pd += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ); + pd += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen); ed++; - - ps2 += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ); + + ps2 += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen); es2++; - } else { - memcpy( ed, es1, sizeof(HEntry) ); - memcpy( pd, ps1, es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen ) ); + } + else + { + memcpy(ed, es1, sizeof(HEntry)); + memcpy(pd, ps1, es1->keylen + ((es1->valisnull) ? 0 : es1->vallen)); ed->pos = pd - STRPTR(out); - pd += es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen ); + pd += es1->keylen + ((es1->valisnull) ? 0 : es1->vallen); ed++; - - ps1 += es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen ); + + ps1 += es1->keylen + ((es1->valisnull) ? 0 : es1->vallen); es1++; } } - while( es1 - ARRPTR(s1) < s1->size ) { - memcpy( ed, es1, sizeof(HEntry) ); - memcpy( pd, ps1, es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen ) ); + while (es1 - ARRPTR(s1) < s1->size) + { + memcpy(ed, es1, sizeof(HEntry)); + memcpy(pd, ps1, es1->keylen + ((es1->valisnull) ? 0 : es1->vallen)); ed->pos = pd - STRPTR(out); - pd += es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen ); + pd += es1->keylen + ((es1->valisnull) ? 0 : es1->vallen); ed++; - - ps1 += es1->keylen + ( (es1->valisnull) ? 0 : es1->vallen ); + + ps1 += es1->keylen + ((es1->valisnull) ? 0 : es1->vallen); es1++; } - while( es2 - ARRPTR(s2) < s2->size ) { - memcpy( ed, es2, sizeof(HEntry) ); - memcpy( pd, ps2, es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ) ); + while (es2 - ARRPTR(s2) < s2->size) + { + memcpy(ed, es2, sizeof(HEntry)); + memcpy(pd, ps2, es2->keylen + ((es2->valisnull) ? 0 : es2->vallen)); ed->pos = pd - STRPTR(out); - pd += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ); + pd += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen); ed++; - - ps2 += es2->keylen + ( (es2->valisnull) ? 0 : es2->vallen ); + + ps2 += es2->keylen + ((es2->valisnull) ? 0 : es2->vallen); es2++; } - if ( ed - ARRPTR(out) != out->size ) { - int buflen=pd-STRPTR(out); + if (ed - ARRPTR(out) != out->size) + { + int buflen = pd - STRPTR(out); + pd = STRPTR(out); out->size = ed - ARRPTR(out); - memmove( STRPTR(out), pd, buflen); + memmove(STRPTR(out), pd, buflen); out->len = CALCDATASIZE(out->size, buflen); } - - PG_FREE_IF_COPY(s1,0); - PG_FREE_IF_COPY(s2,1); + + PG_FREE_IF_COPY(s1, 0); + PG_FREE_IF_COPY(s2, 1); PG_RETURN_POINTER(out); } PG_FUNCTION_INFO_V1(tconvert); -Datum tconvert(PG_FUNCTION_ARGS); +Datum tconvert(PG_FUNCTION_ARGS); Datum -tconvert(PG_FUNCTION_ARGS) { - text *key = PG_GETARG_TEXT_P(0); - text *val = PG_GETARG_TEXT_P(1); - int len; - HStore *out; - - len=CALCDATASIZE(1, VARSIZE(key) + VARSIZE(val) - 2*VARHDRSZ); +tconvert(PG_FUNCTION_ARGS) +{ + text *key = PG_GETARG_TEXT_P(0); + text *val = PG_GETARG_TEXT_P(1); + int len; + HStore *out; + + len = CALCDATASIZE(1, VARSIZE(key) + VARSIZE(val) - 2 * VARHDRSZ); out = palloc(len); - out->len=len; - out->size=1; + out->len = len; + out->size = 1; ARRPTR(out)->keylen = VARSIZE(key) - VARHDRSZ; ARRPTR(out)->vallen = VARSIZE(val) - VARHDRSZ; ARRPTR(out)->valisnull = false; - ARRPTR(out)->pos=0; + ARRPTR(out)->pos = 0; - memcpy( STRPTR(out), VARDATA(key), ARRPTR(out)->keylen ); - memcpy( STRPTR(out) + ARRPTR(out)->keylen, VARDATA(val), ARRPTR(out)->vallen ); - - PG_FREE_IF_COPY(key,0); - PG_FREE_IF_COPY(val,1); + memcpy(STRPTR(out), VARDATA(key), ARRPTR(out)->keylen); + memcpy(STRPTR(out) + ARRPTR(out)->keylen, VARDATA(val), ARRPTR(out)->vallen); + + PG_FREE_IF_COPY(key, 0); + PG_FREE_IF_COPY(val, 1); PG_RETURN_POINTER(out); } PG_FUNCTION_INFO_V1(akeys); -Datum akeys(PG_FUNCTION_ARGS); +Datum akeys(PG_FUNCTION_ARGS); Datum -akeys(PG_FUNCTION_ARGS) { - HStore *hs = PG_GETARG_HS(0); - Datum *d; - ArrayType *a; - HEntry *ptr=ARRPTR(hs); - char *base=STRPTR(hs); - - d=(Datum*)palloc(sizeof(Datum)*(hs->size+1)); - while( ptr-ARRPTR(hs) < hs->size ) { - text *item=(text*)palloc(VARHDRSZ + ptr->keylen); - VARATT_SIZEP(item) = VARHDRSZ+ptr->keylen; +akeys(PG_FUNCTION_ARGS) +{ + HStore *hs = PG_GETARG_HS(0); + Datum *d; + ArrayType *a; + HEntry *ptr = ARRPTR(hs); + char *base = STRPTR(hs); + + d = (Datum *) palloc(sizeof(Datum) * (hs->size + 1)); + while (ptr - ARRPTR(hs) < hs->size) + { + text *item = (text *) palloc(VARHDRSZ + ptr->keylen); + + VARATT_SIZEP(item) = VARHDRSZ + ptr->keylen; memcpy(VARDATA(item), base + ptr->pos, ptr->keylen); - d[ ptr-ARRPTR(hs) ] = PointerGetDatum(item); + d[ptr - ARRPTR(hs)] = PointerGetDatum(item); ptr++; } - + a = construct_array( - d, - hs->size, - TEXTOID, - -1, - false, - 'i' - ); - - ptr=ARRPTR(hs); - while( ptr-ARRPTR(hs) < hs->size ) { - pfree(DatumGetPointer(d[ ptr-ARRPTR(hs) ])); + d, + hs->size, + TEXTOID, + -1, + false, + 'i' + ); + + ptr = ARRPTR(hs); + while (ptr - ARRPTR(hs) < hs->size) + { + pfree(DatumGetPointer(d[ptr - ARRPTR(hs)])); ptr++; } pfree(d); - PG_FREE_IF_COPY(hs,0); + PG_FREE_IF_COPY(hs, 0); PG_RETURN_POINTER(a); } PG_FUNCTION_INFO_V1(avals); -Datum avals(PG_FUNCTION_ARGS); +Datum avals(PG_FUNCTION_ARGS); Datum -avals(PG_FUNCTION_ARGS) { - HStore *hs = PG_GETARG_HS(0); - Datum *d; - ArrayType *a; - HEntry *ptr=ARRPTR(hs); - char *base=STRPTR(hs); - - d=(Datum*)palloc(sizeof(Datum)*(hs->size+1)); - while( ptr-ARRPTR(hs) < hs->size ) { - int vallen = (ptr->valisnull) ? 0 : ptr->vallen; - text *item=(text*)palloc(VARHDRSZ + vallen); - VARATT_SIZEP(item) = VARHDRSZ+vallen; +avals(PG_FUNCTION_ARGS) +{ + HStore *hs = PG_GETARG_HS(0); + Datum *d; + ArrayType *a; + HEntry *ptr = ARRPTR(hs); + char *base = STRPTR(hs); + + d = (Datum *) palloc(sizeof(Datum) * (hs->size + 1)); + while (ptr - ARRPTR(hs) < hs->size) + { + int vallen = (ptr->valisnull) ? 0 : ptr->vallen; + text *item = (text *) palloc(VARHDRSZ + vallen); + + VARATT_SIZEP(item) = VARHDRSZ + vallen; memcpy(VARDATA(item), base + ptr->pos + ptr->keylen, vallen); - d[ ptr-ARRPTR(hs) ] = PointerGetDatum(item); + d[ptr - ARRPTR(hs)] = PointerGetDatum(item); ptr++; } - + a = construct_array( - d, - hs->size, - TEXTOID, - -1, - false, - 'i' - ); - - ptr=ARRPTR(hs); - while( ptr-ARRPTR(hs) < hs->size ) { - pfree(DatumGetPointer(d[ ptr-ARRPTR(hs) ])); + d, + hs->size, + TEXTOID, + -1, + false, + 'i' + ); + + ptr = ARRPTR(hs); + while (ptr - ARRPTR(hs) < hs->size) + { + pfree(DatumGetPointer(d[ptr - ARRPTR(hs)])); ptr++; } pfree(d); - PG_FREE_IF_COPY(hs,0); + PG_FREE_IF_COPY(hs, 0); PG_RETURN_POINTER(a); } -typedef struct { - HStore *hs; - int i; -} AKStore; +typedef struct +{ + HStore *hs; + int i; +} AKStore; static void -setup_firstcall(FuncCallContext *funcctx, HStore *hs) { - MemoryContext oldcontext; - AKStore *st; +setup_firstcall(FuncCallContext *funcctx, HStore * hs) +{ + MemoryContext oldcontext; + AKStore *st; oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - st=(AKStore*)palloc( sizeof(AKStore) ); - st->i=0; - st->hs = (HStore*)palloc(hs->len); - memcpy( st->hs, hs, hs->len ); + st = (AKStore *) palloc(sizeof(AKStore)); + st->i = 0; + st->hs = (HStore *) palloc(hs->len); + memcpy(st->hs, hs, hs->len); - funcctx->user_fctx = (void*)st; + funcctx->user_fctx = (void *) st; MemoryContextSwitchTo(oldcontext); } PG_FUNCTION_INFO_V1(skeys); -Datum skeys(PG_FUNCTION_ARGS); +Datum skeys(PG_FUNCTION_ARGS); Datum -skeys(PG_FUNCTION_ARGS) { - FuncCallContext *funcctx; - AKStore *st; +skeys(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + AKStore *st; + + if (SRF_IS_FIRSTCALL()) + { + HStore *hs = PG_GETARG_HS(0); - if (SRF_IS_FIRSTCALL()) { - HStore *hs = PG_GETARG_HS(0); funcctx = SRF_FIRSTCALL_INIT(); setup_firstcall(funcctx, hs); - PG_FREE_IF_COPY(hs,0); + PG_FREE_IF_COPY(hs, 0); } funcctx = SRF_PERCALL_SETUP(); - st = (AKStore*)funcctx->user_fctx; - - if ( st->i < st->hs->size ) { - HEntry *ptr = &(ARRPTR(st->hs)[st->i]); - text *item=(text*)palloc(VARHDRSZ + ptr->keylen); + st = (AKStore *) funcctx->user_fctx; + + if (st->i < st->hs->size) + { + HEntry *ptr = &(ARRPTR(st->hs)[st->i]); + text *item = (text *) palloc(VARHDRSZ + ptr->keylen); - VARATT_SIZEP(item) = VARHDRSZ+ptr->keylen; + VARATT_SIZEP(item) = VARHDRSZ + ptr->keylen; memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos, ptr->keylen); st->i++; SRF_RETURN_NEXT(funcctx, PointerGetDatum(item)); } - - pfree( st->hs ); - pfree( st ); - SRF_RETURN_DONE(funcctx); + pfree(st->hs); + pfree(st); + + SRF_RETURN_DONE(funcctx); } PG_FUNCTION_INFO_V1(svals); -Datum svals(PG_FUNCTION_ARGS); +Datum svals(PG_FUNCTION_ARGS); Datum -svals(PG_FUNCTION_ARGS) { - FuncCallContext *funcctx; - AKStore *st; +svals(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + AKStore *st; + + if (SRF_IS_FIRSTCALL()) + { + HStore *hs = PG_GETARG_HS(0); - if (SRF_IS_FIRSTCALL()) { - HStore *hs = PG_GETARG_HS(0); funcctx = SRF_FIRSTCALL_INIT(); setup_firstcall(funcctx, hs); - PG_FREE_IF_COPY(hs,0); + PG_FREE_IF_COPY(hs, 0); } funcctx = SRF_PERCALL_SETUP(); - st = (AKStore*)funcctx->user_fctx; - - if ( st->i < st->hs->size ) { - HEntry *ptr = &(ARRPTR(st->hs)[st->i]); + st = (AKStore *) funcctx->user_fctx; - if ( ptr->valisnull ) { - ReturnSetInfo *rsi; + if (st->i < st->hs->size) + { + HEntry *ptr = &(ARRPTR(st->hs)[st->i]); + + if (ptr->valisnull) + { + ReturnSetInfo *rsi; st->i++; (funcctx)->call_cntr++; rsi = (ReturnSetInfo *) fcinfo->resultinfo; rsi->isDone = ExprMultipleResult; PG_RETURN_NULL(); - } else { - int vallen = ptr->vallen; - text *item=(text*)palloc(VARHDRSZ + vallen); + } + else + { + int vallen = ptr->vallen; + text *item = (text *) palloc(VARHDRSZ + vallen); - VARATT_SIZEP(item) = VARHDRSZ+vallen; + VARATT_SIZEP(item) = VARHDRSZ + vallen; memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos + ptr->keylen, vallen); st->i++; SRF_RETURN_NEXT(funcctx, PointerGetDatum(item)); } } - - pfree( st->hs ); - pfree( st ); - SRF_RETURN_DONE(funcctx); + pfree(st->hs); + pfree(st); + + SRF_RETURN_DONE(funcctx); } PG_FUNCTION_INFO_V1(hs_contains); -Datum hs_contains(PG_FUNCTION_ARGS); +Datum hs_contains(PG_FUNCTION_ARGS); Datum -hs_contains(PG_FUNCTION_ARGS) { - HStore *val = PG_GETARG_HS(0); - HStore *tmpl = PG_GETARG_HS(1); - bool res = true; - HEntry *te = ARRPTR(tmpl); - char *vv = STRPTR(val); - char *tv = STRPTR(tmpl); - - while(res && te-ARRPTR(tmpl) < tmpl->size) { - HEntry *entry = findkey(val, tv + te->pos, te->keylen); - if ( entry ) { - if ( ! te->valisnull ) { - if ( entry->valisnull || !( - te->vallen==entry->vallen && - strncmp( - vv + entry->pos + entry->keylen, - tv + te->pos + te->keylen, - te->vallen ) == 0 - ) ) - res=false; +hs_contains(PG_FUNCTION_ARGS) +{ + HStore *val = PG_GETARG_HS(0); + HStore *tmpl = PG_GETARG_HS(1); + bool res = true; + HEntry *te = ARRPTR(tmpl); + char *vv = STRPTR(val); + char *tv = STRPTR(tmpl); + + while (res && te - ARRPTR(tmpl) < tmpl->size) + { + HEntry *entry = findkey(val, tv + te->pos, te->keylen); + + if (entry) + { + if (!te->valisnull) + { + if (entry->valisnull || !( + te->vallen == entry->vallen && + strncmp( + vv + entry->pos + entry->keylen, + tv + te->pos + te->keylen, + te->vallen) == 0 + )) + res = false; } - } else + } + else res = false; te++; } - PG_FREE_IF_COPY(val,0); - PG_FREE_IF_COPY(tmpl,1); + PG_FREE_IF_COPY(val, 0); + PG_FREE_IF_COPY(tmpl, 1); PG_RETURN_BOOL(res); } - + PG_FUNCTION_INFO_V1(hs_contained); -Datum hs_contained(PG_FUNCTION_ARGS); +Datum hs_contained(PG_FUNCTION_ARGS); Datum -hs_contained(PG_FUNCTION_ARGS) { - PG_RETURN_DATUM( DirectFunctionCall2( - hs_contains, - PG_GETARG_DATUM(1), - PG_GETARG_DATUM(0) - )); +hs_contained(PG_FUNCTION_ARGS) +{ + PG_RETURN_DATUM(DirectFunctionCall2( + hs_contains, + PG_GETARG_DATUM(1), + PG_GETARG_DATUM(0) + )); } PG_FUNCTION_INFO_V1(each); -Datum each(PG_FUNCTION_ARGS); +Datum each(PG_FUNCTION_ARGS); Datum -each(PG_FUNCTION_ARGS) { - FuncCallContext *funcctx; - AKStore *st; +each(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + AKStore *st; - if (SRF_IS_FIRSTCALL()) { - TupleDesc tupdesc; - MemoryContext oldcontext; - HStore *hs = PG_GETARG_HS(0); + if (SRF_IS_FIRSTCALL()) + { + TupleDesc tupdesc; + MemoryContext oldcontext; + HStore *hs = PG_GETARG_HS(0); funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - st=(AKStore*)palloc( sizeof(AKStore) ); - st->i=0; - st->hs = (HStore*)palloc(hs->len); - memcpy( st->hs, hs, hs->len ); - funcctx->user_fctx = (void*)st; - + st = (AKStore *) palloc(sizeof(AKStore)); + st->i = 0; + st->hs = (HStore *) palloc(hs->len); + memcpy(st->hs, hs, hs->len); + funcctx->user_fctx = (void *) st; + tupdesc = RelationNameGetTupleDesc("hs_each"); funcctx->slot = TupleDescGetSlot(tupdesc); funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc); MemoryContextSwitchTo(oldcontext); - PG_FREE_IF_COPY(hs,0); + PG_FREE_IF_COPY(hs, 0); } funcctx = SRF_PERCALL_SETUP(); - st = (AKStore*)funcctx->user_fctx; - - if ( st->i < st->hs->size ) { - HEntry *ptr = &(ARRPTR(st->hs)[st->i]); - Datum res, dvalues[2]; - char nulls[] = {' ', ' '}; - text *item; - HeapTuple tuple; - - item=(text*)palloc(VARHDRSZ + ptr->keylen); - VARATT_SIZEP(item) = VARHDRSZ+ptr->keylen; + st = (AKStore *) funcctx->user_fctx; + + if (st->i < st->hs->size) + { + HEntry *ptr = &(ARRPTR(st->hs)[st->i]); + Datum res, + dvalues[2]; + char nulls[] = {' ', ' '}; + text *item; + HeapTuple tuple; + + item = (text *) palloc(VARHDRSZ + ptr->keylen); + VARATT_SIZEP(item) = VARHDRSZ + ptr->keylen; memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos, ptr->keylen); dvalues[0] = PointerGetDatum(item); - if ( ptr->valisnull ) { - dvalues[1]=(Datum)0; - nulls[1]='n'; - } else { - int vallen = ptr->vallen; + if (ptr->valisnull) + { + dvalues[1] = (Datum) 0; + nulls[1] = 'n'; + } + else + { + int vallen = ptr->vallen; - item=(text*)palloc(VARHDRSZ + vallen); - VARATT_SIZEP(item) = VARHDRSZ+vallen; + item = (text *) palloc(VARHDRSZ + vallen); + VARATT_SIZEP(item) = VARHDRSZ + vallen; memcpy(VARDATA(item), STRPTR(st->hs) + ptr->pos + ptr->keylen, vallen); dvalues[1] = PointerGetDatum(item); } @@ -551,17 +616,15 @@ each(PG_FUNCTION_ARGS) { tuple = heap_formtuple(funcctx->attinmeta->tupdesc, dvalues, nulls); res = TupleGetDatum(funcctx->slot, tuple); - pfree( DatumGetPointer(dvalues[0]) ); - if ( nulls[1] != 'n' ) - pfree( DatumGetPointer(dvalues[1]) ); + pfree(DatumGetPointer(dvalues[0])); + if (nulls[1] != 'n') + pfree(DatumGetPointer(dvalues[1])); SRF_RETURN_NEXT(funcctx, PointerGetDatum(res)); } - - pfree( st->hs ); - pfree( st ); - - SRF_RETURN_DONE(funcctx); -} + pfree(st->hs); + pfree(st); + SRF_RETURN_DONE(funcctx); +} |
