PostgreSQL Source Code  git master
hstore_op.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "hstore.h"
#include "utils/builtins.h"
#include "utils/hashutils.h"
#include "utils/memutils.h"
Include dependency graph for hstore_op.c:

Go to the source code of this file.

Functions

 HSTORE_POLLUTE (hstore_fetchval, fetchval)
 
 HSTORE_POLLUTE (hstore_exists, exists)
 
 HSTORE_POLLUTE (hstore_defined, defined)
 
 HSTORE_POLLUTE (hstore_delete, delete)
 
 HSTORE_POLLUTE (hstore_concat, hs_concat)
 
 HSTORE_POLLUTE (hstore_contains, hs_contains)
 
 HSTORE_POLLUTE (hstore_contained, hs_contained)
 
 HSTORE_POLLUTE (hstore_akeys, akeys)
 
 HSTORE_POLLUTE (hstore_avals, avals)
 
 HSTORE_POLLUTE (hstore_skeys, skeys)
 
 HSTORE_POLLUTE (hstore_svals, svals)
 
 HSTORE_POLLUTE (hstore_each, each)
 
int hstoreFindKey (HStore *hs, int *lowbound, char *key, int keylen)
 
PairshstoreArrayToPairs (ArrayType *a, int *npairs)
 
 PG_FUNCTION_INFO_V1 (hstore_fetchval)
 
Datum hstore_fetchval (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_exists)
 
Datum hstore_exists (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_exists_any)
 
Datum hstore_exists_any (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_exists_all)
 
Datum hstore_exists_all (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_defined)
 
Datum hstore_defined (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_delete)
 
Datum hstore_delete (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_delete_array)
 
Datum hstore_delete_array (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_delete_hstore)
 
Datum hstore_delete_hstore (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_concat)
 
Datum hstore_concat (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_slice_to_array)
 
Datum hstore_slice_to_array (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_slice_to_hstore)
 
Datum hstore_slice_to_hstore (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_akeys)
 
Datum hstore_akeys (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_avals)
 
Datum hstore_avals (PG_FUNCTION_ARGS)
 
static ArrayTypehstore_to_array_internal (HStore *hs, int ndims)
 
 PG_FUNCTION_INFO_V1 (hstore_to_array)
 
Datum hstore_to_array (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_to_matrix)
 
Datum hstore_to_matrix (PG_FUNCTION_ARGS)
 
static void setup_firstcall (FuncCallContext *funcctx, HStore *hs, FunctionCallInfo fcinfo)
 
 PG_FUNCTION_INFO_V1 (hstore_skeys)
 
Datum hstore_skeys (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_svals)
 
Datum hstore_svals (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_contains)
 
Datum hstore_contains (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_contained)
 
Datum hstore_contained (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_each)
 
Datum hstore_each (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_cmp)
 
Datum hstore_cmp (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_eq)
 
Datum hstore_eq (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_ne)
 
Datum hstore_ne (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_gt)
 
Datum hstore_gt (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_ge)
 
Datum hstore_ge (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_lt)
 
Datum hstore_lt (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_le)
 
Datum hstore_le (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_hash)
 
Datum hstore_hash (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_hash_extended)
 
Datum hstore_hash_extended (PG_FUNCTION_ARGS)
 

Function Documentation

◆ hstore_akeys()

Datum hstore_akeys ( PG_FUNCTION_ARGS  )

Definition at line 696 of file hstore_op.c.

References ARRPTR, construct_array(), construct_empty_array(), cstring_to_text_with_len(), HS_COUNT, hstore_avals(), HSTORE_KEY, HSTORE_KEYLEN, i, palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_POINTER, PointerGetDatum, and STRPTR.

Referenced by hstore_slice_to_hstore().

697 {
698  HStore *hs = PG_GETARG_HSTORE_P(0);
699  Datum *d;
700  ArrayType *a;
701  HEntry *entries = ARRPTR(hs);
702  char *base = STRPTR(hs);
703  int count = HS_COUNT(hs);
704  int i;
705 
706  if (count == 0)
707  {
708  a = construct_empty_array(TEXTOID);
710  }
711 
712  d = (Datum *) palloc(sizeof(Datum) * count);
713 
714  for (i = 0; i < count; ++i)
715  {
716  text *t = cstring_to_text_with_len(HSTORE_KEY(entries, base, i),
717  HSTORE_KEYLEN(entries, i));
718 
719  d[i] = PointerGetDatum(t);
720  }
721 
722  a = construct_array(d, count,
723  TEXTOID, -1, false, 'i');
724 
726 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define PointerGetDatum(X)
Definition: postgres.h:556
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3291
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3410
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
uintptr_t Datum
Definition: postgres.h:367
Definition: hstore.h:18
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
Definition: c.h:556
#define ARRPTR(x)
Definition: cube.c:24

◆ hstore_avals()

Datum hstore_avals ( PG_FUNCTION_ARGS  )

Definition at line 731 of file hstore_op.c.

References ARRPTR, construct_empty_array(), construct_md_array(), cstring_to_text_with_len(), HS_COUNT, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, palloc(), PG_GETARG_HSTORE_P, PG_RETURN_POINTER, PointerGetDatum, and STRPTR.

Referenced by hstore_akeys().

732 {
733  HStore *hs = PG_GETARG_HSTORE_P(0);
734  Datum *d;
735  bool *nulls;
736  ArrayType *a;
737  HEntry *entries = ARRPTR(hs);
738  char *base = STRPTR(hs);
739  int count = HS_COUNT(hs);
740  int lb = 1;
741  int i;
742 
743  if (count == 0)
744  {
745  a = construct_empty_array(TEXTOID);
747  }
748 
749  d = (Datum *) palloc(sizeof(Datum) * count);
750  nulls = (bool *) palloc(sizeof(bool) * count);
751 
752  for (i = 0; i < count; ++i)
753  {
754  if (HSTORE_VALISNULL(entries, i))
755  {
756  d[i] = (Datum) 0;
757  nulls[i] = true;
758  }
759  else
760  {
761  text *item = cstring_to_text_with_len(HSTORE_VAL(entries, base, i),
762  HSTORE_VALLEN(entries, i));
763 
764  d[i] = PointerGetDatum(item);
765  nulls[i] = false;
766  }
767  }
768 
769  a = construct_md_array(d, nulls, 1, &count, &lb,
770  TEXTOID, -1, false, 'i');
771 
773 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define PointerGetDatum(X)
Definition: postgres.h:556
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3410
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define HS_COUNT(hsp_)
Definition: hstore.h:61
uintptr_t Datum
Definition: postgres.h:367
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
Definition: c.h:556
#define ARRPTR(x)
Definition: cube.c:24
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3326

◆ hstore_cmp()

Datum hstore_cmp ( PG_FUNCTION_ARGS  )

Definition at line 1087 of file hstore_op.c.

References ARRPTR, HS_COUNT, HSE_ENDPOS, HSE_ISNULL, hstore_eq(), i, Min, PG_FREE_IF_COPY, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_INT32, and STRPTR.

Referenced by hstore_each(), hstore_eq(), hstore_ge(), hstore_gt(), hstore_le(), hstore_lt(), and hstore_ne().

1088 {
1089  HStore *hs1 = PG_GETARG_HSTORE_P(0);
1090  HStore *hs2 = PG_GETARG_HSTORE_P(1);
1091  int hcount1 = HS_COUNT(hs1);
1092  int hcount2 = HS_COUNT(hs2);
1093  int res = 0;
1094 
1095  if (hcount1 == 0 || hcount2 == 0)
1096  {
1097  /*
1098  * if either operand is empty, and the other is nonempty, the nonempty
1099  * one is larger. If both are empty they are equal.
1100  */
1101  if (hcount1 > 0)
1102  res = 1;
1103  else if (hcount2 > 0)
1104  res = -1;
1105  }
1106  else
1107  {
1108  /* here we know both operands are nonempty */
1109  char *str1 = STRPTR(hs1);
1110  char *str2 = STRPTR(hs2);
1111  HEntry *ent1 = ARRPTR(hs1);
1112  HEntry *ent2 = ARRPTR(hs2);
1113  size_t len1 = HSE_ENDPOS(ent1[2 * hcount1 - 1]);
1114  size_t len2 = HSE_ENDPOS(ent2[2 * hcount2 - 1]);
1115 
1116  res = memcmp(str1, str2, Min(len1, len2));
1117 
1118  if (res == 0)
1119  {
1120  if (len1 > len2)
1121  res = 1;
1122  else if (len1 < len2)
1123  res = -1;
1124  else if (hcount1 > hcount2)
1125  res = 1;
1126  else if (hcount2 > hcount1)
1127  res = -1;
1128  else
1129  {
1130  int count = hcount1 * 2;
1131  int i;
1132 
1133  for (i = 0; i < count; ++i)
1134  if (HSE_ENDPOS(ent1[i]) != HSE_ENDPOS(ent2[i]) ||
1135  HSE_ISNULL(ent1[i]) != HSE_ISNULL(ent2[i]))
1136  break;
1137  if (i < count)
1138  {
1139  if (HSE_ENDPOS(ent1[i]) < HSE_ENDPOS(ent2[i]))
1140  res = -1;
1141  else if (HSE_ENDPOS(ent1[i]) > HSE_ENDPOS(ent2[i]))
1142  res = 1;
1143  else if (HSE_ISNULL(ent1[i]))
1144  res = 1;
1145  else if (HSE_ISNULL(ent2[i]))
1146  res = -1;
1147  }
1148  }
1149  }
1150  else
1151  {
1152  res = (res > 0) ? 1 : -1;
1153  }
1154  }
1155 
1156  /*
1157  * this is a btree support function; this is one of the few places where
1158  * memory needs to be explicitly freed.
1159  */
1160  PG_FREE_IF_COPY(hs1, 0);
1161  PG_FREE_IF_COPY(hs2, 1);
1162  PG_RETURN_INT32(res);
1163 }
#define HSE_ENDPOS(he_)
Definition: hstore.h:30
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define Min(x, y)
Definition: c.h:911
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define HSE_ISNULL(he_)
Definition: hstore.h:29
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: hstore.h:18
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:24

◆ hstore_concat()

Datum hstore_concat ( PG_FUNCTION_ARGS  )

Definition at line 473 of file hstore_op.c.

References ARRPTR, difference(), HS_COPYITEM, HS_COUNT, HS_FINALIZE, HS_FIXSIZE, HS_SETCOUNT, HSHRDSIZE, HSTORE_KEY, HSTORE_KEYLEN, hstore_slice_to_array(), HSTORE_VALISNULL, HSTORE_VALLEN, palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_POINTER, s1, s2, SET_VARSIZE, STRPTR, and VARSIZE.

Referenced by hstore_delete_hstore().

474 {
477  HStore *out = palloc(VARSIZE(s1) + VARSIZE(s2));
478  char *ps1,
479  *ps2,
480  *bufd,
481  *pd;
482  HEntry *es1,
483  *es2,
484  *ed;
485  int s1idx;
486  int s2idx;
487  int s1count = HS_COUNT(s1);
488  int s2count = HS_COUNT(s2);
489  int outcount = 0;
490 
491  SET_VARSIZE(out, VARSIZE(s1) + VARSIZE(s2) - HSHRDSIZE);
492  HS_SETCOUNT(out, s1count + s2count);
493 
494  if (s1count == 0)
495  {
496  /* return a copy of the input, unchanged */
497  memcpy(out, s2, VARSIZE(s2));
498  HS_FIXSIZE(out, s2count);
499  HS_SETCOUNT(out, s2count);
500  PG_RETURN_POINTER(out);
501  }
502 
503  if (s2count == 0)
504  {
505  /* return a copy of the input, unchanged */
506  memcpy(out, s1, VARSIZE(s1));
507  HS_FIXSIZE(out, s1count);
508  HS_SETCOUNT(out, s1count);
509  PG_RETURN_POINTER(out);
510  }
511 
512  ps1 = STRPTR(s1);
513  ps2 = STRPTR(s2);
514  bufd = pd = STRPTR(out);
515  es1 = ARRPTR(s1);
516  es2 = ARRPTR(s2);
517  ed = ARRPTR(out);
518 
519  /*
520  * this is in effect a merge between s1 and s2, both of which are already
521  * sorted by (keylen,key); we take s2 for equal keys
522  */
523 
524  for (s1idx = s2idx = 0; s1idx < s1count || s2idx < s2count; ++outcount)
525  {
526  int difference;
527 
528  if (s1idx >= s1count)
529  difference = 1;
530  else if (s2idx >= s2count)
531  difference = -1;
532  else
533  {
534  int s1keylen = HSTORE_KEYLEN(es1, s1idx);
535  int s2keylen = HSTORE_KEYLEN(es2, s2idx);
536 
537  if (s1keylen == s2keylen)
538  difference = memcmp(HSTORE_KEY(es1, ps1, s1idx),
539  HSTORE_KEY(es2, ps2, s2idx),
540  s1keylen);
541  else
542  difference = (s1keylen > s2keylen) ? 1 : -1;
543  }
544 
545  if (difference >= 0)
546  {
547  HS_COPYITEM(ed, bufd, pd,
548  HSTORE_KEY(es2, ps2, s2idx), HSTORE_KEYLEN(es2, s2idx),
549  HSTORE_VALLEN(es2, s2idx), HSTORE_VALISNULL(es2, s2idx));
550  ++s2idx;
551  if (difference == 0)
552  ++s1idx;
553  }
554  else
555  {
556  HS_COPYITEM(ed, bufd, pd,
557  HSTORE_KEY(es1, ps1, s1idx), HSTORE_KEYLEN(es1, s1idx),
558  HSTORE_VALLEN(es1, s1idx), HSTORE_VALISNULL(es1, s1idx));
559  ++s1idx;
560  }
561  }
562 
563  HS_FINALIZE(out, outcount, bufd, pd);
564 
565  PG_RETURN_POINTER(out);
566 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define VARSIZE(PTR)
Definition: postgres.h:303
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
char * s1
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define HS_FINALIZE(hsp_, count_, buf_, ptr_)
Definition: hstore.h:129
char * s2
Datum difference(PG_FUNCTION_ARGS)
#define HSHRDSIZE
Definition: hstore.h:71
Definition: hstore.h:18
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
#define HS_COPYITEM(dent_, dbuf_, dptr_, sptr_, klen_, vlen_, vnull_)
Definition: hstore.h:99
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
#define ARRPTR(x)
Definition: cube.c:24
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62
#define HS_FIXSIZE(hsp_, count_)
Definition: hstore.h:143

◆ hstore_contained()

Datum hstore_contained ( PG_FUNCTION_ARGS  )

Definition at line 1015 of file hstore_op.c.

References DirectFunctionCall2, hstore_contains(), hstore_each(), PG_FUNCTION_INFO_V1(), PG_GETARG_DATUM, and PG_RETURN_DATUM.

Referenced by hstore_contains().

1016 {
1018  PG_GETARG_DATUM(1),
1019  PG_GETARG_DATUM(0)
1020  ));
1021 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
Datum hstore_contains(PG_FUNCTION_ARGS)
Definition: hstore_op.c:967
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:617

◆ hstore_contains()

Datum hstore_contains ( PG_FUNCTION_ARGS  )

Definition at line 967 of file hstore_op.c.

References ARRPTR, HS_COUNT, hstore_contained(), HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, hstoreFindKey(), i, idx(), PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_BOOL, STRPTR, and val.

Referenced by hstore_contained(), and hstore_svals().

968 {
970  HStore *tmpl = PG_GETARG_HSTORE_P(1);
971  bool res = true;
972  HEntry *te = ARRPTR(tmpl);
973  char *tstr = STRPTR(tmpl);
974  HEntry *ve = ARRPTR(val);
975  char *vstr = STRPTR(val);
976  int tcount = HS_COUNT(tmpl);
977  int lastidx = 0;
978  int i;
979 
980  /*
981  * we exploit the fact that keys in "tmpl" are in strictly increasing
982  * order to narrow the hstoreFindKey search; each search can start one
983  * entry past the previous "found" entry, or at the lower bound of the
984  * search
985  */
986 
987  for (i = 0; res && i < tcount; ++i)
988  {
989  int idx = hstoreFindKey(val, &lastidx,
990  HSTORE_KEY(te, tstr, i),
991  HSTORE_KEYLEN(te, i));
992 
993  if (idx >= 0)
994  {
995  bool nullval = HSTORE_VALISNULL(te, i);
996  int vallen = HSTORE_VALLEN(te, i);
997 
998  if (nullval != HSTORE_VALISNULL(ve, idx) ||
999  (!nullval && (vallen != HSTORE_VALLEN(ve, idx) ||
1000  memcmp(HSTORE_VAL(te, tstr, i),
1001  HSTORE_VAL(ve, vstr, idx),
1002  vallen) != 0)))
1003  res = false;
1004  }
1005  else
1006  res = false;
1007  }
1008 
1009  PG_RETURN_BOOL(res);
1010 }
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:24
long val
Definition: informix.c:664

◆ hstore_defined()

Datum hstore_defined ( PG_FUNCTION_ARGS  )

Definition at line 232 of file hstore_op.c.

References ARRPTR, hstore_delete(), HSTORE_VALISNULL, hstoreFindKey(), idx(), sort-test::key, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by hstore_exists_all().

233 {
234  HStore *hs = PG_GETARG_HSTORE_P(0);
235  text *key = PG_GETARG_TEXT_PP(1);
236  HEntry *entries = ARRPTR(hs);
237  int idx = hstoreFindKey(hs, NULL,
238  VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
239  bool res = (idx >= 0 && !HSTORE_VALISNULL(entries, idx));
240 
241  PG_RETURN_BOOL(res);
242 }
Definition: hstore.h:44
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Definition: hstore.h:18
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:556
#define ARRPTR(x)
Definition: cube.c:24

◆ hstore_delete()

Datum hstore_delete ( PG_FUNCTION_ARGS  )

Definition at line 247 of file hstore_op.c.

References ARRPTR, HS_COPYITEM, HS_COUNT, HS_FINALIZE, HS_SETCOUNT, hstore_delete_array(), HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VALISNULL, HSTORE_VALLEN, i, sort-test::key, palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_GETARG_TEXT_PP, PG_RETURN_POINTER, SET_VARSIZE, STRPTR, VARDATA_ANY, VARSIZE, and VARSIZE_ANY_EXHDR.

Referenced by hstore_defined().

248 {
249  HStore *hs = PG_GETARG_HSTORE_P(0);
250  text *key = PG_GETARG_TEXT_PP(1);
251  char *keyptr = VARDATA_ANY(key);
252  int keylen = VARSIZE_ANY_EXHDR(key);
253  HStore *out = palloc(VARSIZE(hs));
254  char *bufs,
255  *bufd,
256  *ptrd;
257  HEntry *es,
258  *ed;
259  int i;
260  int count = HS_COUNT(hs);
261  int outcount = 0;
262 
263  SET_VARSIZE(out, VARSIZE(hs));
264  HS_SETCOUNT(out, count); /* temporary! */
265 
266  bufs = STRPTR(hs);
267  es = ARRPTR(hs);
268  bufd = ptrd = STRPTR(out);
269  ed = ARRPTR(out);
270 
271  for (i = 0; i < count; ++i)
272  {
273  int len = HSTORE_KEYLEN(es, i);
274  char *ptrs = HSTORE_KEY(es, bufs, i);
275 
276  if (!(len == keylen && memcmp(ptrs, keyptr, keylen) == 0))
277  {
278  int vallen = HSTORE_VALLEN(es, i);
279 
280  HS_COPYITEM(ed, bufd, ptrd, ptrs, len, vallen,
281  HSTORE_VALISNULL(es, i));
282  ++outcount;
283  }
284  }
285 
286  HS_FINALIZE(out, outcount, bufd, ptrd);
287 
288  PG_RETURN_POINTER(out);
289 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define VARSIZE(PTR)
Definition: postgres.h:303
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define HS_FINALIZE(hsp_, count_, buf_, ptr_)
Definition: hstore.h:129
Definition: hstore.h:18
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
Definition: c.h:556
#define HS_COPYITEM(dent_, dbuf_, dptr_, sptr_, klen_, vlen_, vnull_)
Definition: hstore.h:99
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
#define ARRPTR(x)
Definition: cube.c:24
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62

◆ hstore_delete_array()

Datum hstore_delete_array ( PG_FUNCTION_ARGS  )

Definition at line 294 of file hstore_op.c.

References ARRPTR, difference(), HS_COPYITEM, HS_COUNT, HS_FINALIZE, HS_FIXSIZE, HS_SETCOUNT, hstore_delete_hstore(), HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VALISNULL, HSTORE_VALLEN, hstoreArrayToPairs(), i, sort-test::key, Pairs::keylen, palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_HSTORE_P, PG_RETURN_POINTER, SET_VARSIZE, STRPTR, and VARSIZE.

Referenced by hstore_delete().

295 {
296  HStore *hs = PG_GETARG_HSTORE_P(0);
297  HStore *out = palloc(VARSIZE(hs));
298  int hs_count = HS_COUNT(hs);
299  char *ps,
300  *bufd,
301  *pd;
302  HEntry *es,
303  *ed;
304  int i,
305  j;
306  int outcount = 0;
307  ArrayType *key_array = PG_GETARG_ARRAYTYPE_P(1);
308  int nkeys;
309  Pairs *key_pairs = hstoreArrayToPairs(key_array, &nkeys);
310 
311  SET_VARSIZE(out, VARSIZE(hs));
312  HS_SETCOUNT(out, hs_count); /* temporary! */
313 
314  ps = STRPTR(hs);
315  es = ARRPTR(hs);
316  bufd = pd = STRPTR(out);
317  ed = ARRPTR(out);
318 
319  if (nkeys == 0)
320  {
321  /* return a copy of the input, unchanged */
322  memcpy(out, hs, VARSIZE(hs));
323  HS_FIXSIZE(out, hs_count);
324  HS_SETCOUNT(out, hs_count);
325  PG_RETURN_POINTER(out);
326  }
327 
328  /*
329  * this is in effect a merge between hs and key_pairs, both of which are
330  * already sorted by (keylen,key); we take keys from hs only
331  */
332 
333  for (i = j = 0; i < hs_count;)
334  {
335  int difference;
336 
337  if (j >= nkeys)
338  difference = -1;
339  else
340  {
341  int skeylen = HSTORE_KEYLEN(es, i);
342 
343  if (skeylen == key_pairs[j].keylen)
344  difference = memcmp(HSTORE_KEY(es, ps, i),
345  key_pairs[j].key,
346  key_pairs[j].keylen);
347  else
348  difference = (skeylen > key_pairs[j].keylen) ? 1 : -1;
349  }
350 
351  if (difference > 0)
352  ++j;
353  else if (difference == 0)
354  ++i, ++j;
355  else
356  {
357  HS_COPYITEM(ed, bufd, pd,
358  HSTORE_KEY(es, ps, i), HSTORE_KEYLEN(es, i),
359  HSTORE_VALLEN(es, i), HSTORE_VALISNULL(es, i));
360  ++outcount;
361  ++i;
362  }
363  }
364 
365  HS_FINALIZE(out, outcount, bufd, pd);
366 
367  PG_RETURN_POINTER(out);
368 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define VARSIZE(PTR)
Definition: postgres.h:303
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define HS_FINALIZE(hsp_, count_, buf_, ptr_)
Definition: hstore.h:129
Datum difference(PG_FUNCTION_ARGS)
Pairs * hstoreArrayToPairs(ArrayType *a, int *npairs)
Definition: hstore_op.c:73
size_t keylen
Definition: hstore.h:165
Definition: hstore.h:18
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
#define HS_COPYITEM(dent_, dbuf_, dptr_, sptr_, klen_, vlen_, vnull_)
Definition: hstore.h:99
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
#define ARRPTR(x)
Definition: cube.c:24
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62
#define HS_FIXSIZE(hsp_, count_)
Definition: hstore.h:143
Definition: hstore.h:161

◆ hstore_delete_hstore()

Datum hstore_delete_hstore ( PG_FUNCTION_ARGS  )

Definition at line 373 of file hstore_op.c.

References ARRPTR, difference(), HS_COPYITEM, HS_COUNT, HS_FINALIZE, HS_FIXSIZE, HS_SETCOUNT, hstore_concat(), HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_POINTER, SET_VARSIZE, STRPTR, and VARSIZE.

Referenced by hstore_delete_array().

374 {
375  HStore *hs = PG_GETARG_HSTORE_P(0);
376  HStore *hs2 = PG_GETARG_HSTORE_P(1);
377  HStore *out = palloc(VARSIZE(hs));
378  int hs_count = HS_COUNT(hs);
379  int hs2_count = HS_COUNT(hs2);
380  char *ps,
381  *ps2,
382  *bufd,
383  *pd;
384  HEntry *es,
385  *es2,
386  *ed;
387  int i,
388  j;
389  int outcount = 0;
390 
391  SET_VARSIZE(out, VARSIZE(hs));
392  HS_SETCOUNT(out, hs_count); /* temporary! */
393 
394  ps = STRPTR(hs);
395  es = ARRPTR(hs);
396  ps2 = STRPTR(hs2);
397  es2 = ARRPTR(hs2);
398  bufd = pd = STRPTR(out);
399  ed = ARRPTR(out);
400 
401  if (hs2_count == 0)
402  {
403  /* return a copy of the input, unchanged */
404  memcpy(out, hs, VARSIZE(hs));
405  HS_FIXSIZE(out, hs_count);
406  HS_SETCOUNT(out, hs_count);
407  PG_RETURN_POINTER(out);
408  }
409 
410  /*
411  * this is in effect a merge between hs and hs2, both of which are already
412  * sorted by (keylen,key); we take keys from hs only; for equal keys, we
413  * take the value from hs unless the values are equal
414  */
415 
416  for (i = j = 0; i < hs_count;)
417  {
418  int difference;
419 
420  if (j >= hs2_count)
421  difference = -1;
422  else
423  {
424  int skeylen = HSTORE_KEYLEN(es, i);
425  int s2keylen = HSTORE_KEYLEN(es2, j);
426 
427  if (skeylen == s2keylen)
428  difference = memcmp(HSTORE_KEY(es, ps, i),
429  HSTORE_KEY(es2, ps2, j),
430  skeylen);
431  else
432  difference = (skeylen > s2keylen) ? 1 : -1;
433  }
434 
435  if (difference > 0)
436  ++j;
437  else if (difference == 0)
438  {
439  int svallen = HSTORE_VALLEN(es, i);
440  int snullval = HSTORE_VALISNULL(es, i);
441 
442  if (snullval != HSTORE_VALISNULL(es2, j) ||
443  (!snullval && (svallen != HSTORE_VALLEN(es2, j) ||
444  memcmp(HSTORE_VAL(es, ps, i),
445  HSTORE_VAL(es2, ps2, j),
446  svallen) != 0)))
447  {
448  HS_COPYITEM(ed, bufd, pd,
449  HSTORE_KEY(es, ps, i), HSTORE_KEYLEN(es, i),
450  svallen, snullval);
451  ++outcount;
452  }
453  ++i, ++j;
454  }
455  else
456  {
457  HS_COPYITEM(ed, bufd, pd,
458  HSTORE_KEY(es, ps, i), HSTORE_KEYLEN(es, i),
459  HSTORE_VALLEN(es, i), HSTORE_VALISNULL(es, i));
460  ++outcount;
461  ++i;
462  }
463  }
464 
465  HS_FINALIZE(out, outcount, bufd, pd);
466 
467  PG_RETURN_POINTER(out);
468 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define VARSIZE(PTR)
Definition: postgres.h:303
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define HS_FINALIZE(hsp_, count_, buf_, ptr_)
Definition: hstore.h:129
Datum difference(PG_FUNCTION_ARGS)
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
#define HS_COPYITEM(dent_, dbuf_, dptr_, sptr_, klen_, vlen_, vnull_)
Definition: hstore.h:99
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
#define ARRPTR(x)
Definition: cube.c:24
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62
#define HS_FIXSIZE(hsp_, count_)
Definition: hstore.h:143

◆ hstore_each()

Datum hstore_each ( PG_FUNCTION_ARGS  )

Definition at line 1026 of file hstore_op.c.

References ARRPTR, FuncCallContext::call_cntr, cstring_to_text_with_len(), heap_form_tuple(), HeapTupleGetDatum, HS_COUNT, hstore_cmp(), HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PointerGetDatum, setup_firstcall(), SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, STRPTR, FuncCallContext::tuple_desc, and FuncCallContext::user_fctx.

Referenced by hstore_contained().

1027 {
1028  FuncCallContext *funcctx;
1029  HStore *hs;
1030  int i;
1031 
1032  if (SRF_IS_FIRSTCALL())
1033  {
1034  hs = PG_GETARG_HSTORE_P(0);
1035  funcctx = SRF_FIRSTCALL_INIT();
1036  setup_firstcall(funcctx, hs, fcinfo);
1037  }
1038 
1039  funcctx = SRF_PERCALL_SETUP();
1040  hs = (HStore *) funcctx->user_fctx;
1041  i = funcctx->call_cntr;
1042 
1043  if (i < HS_COUNT(hs))
1044  {
1045  HEntry *entries = ARRPTR(hs);
1046  char *ptr = STRPTR(hs);
1047  Datum res,
1048  dvalues[2];
1049  bool nulls[2] = {false, false};
1050  text *item;
1051  HeapTuple tuple;
1052 
1053  item = cstring_to_text_with_len(HSTORE_KEY(entries, ptr, i),
1054  HSTORE_KEYLEN(entries, i));
1055  dvalues[0] = PointerGetDatum(item);
1056 
1057  if (HSTORE_VALISNULL(entries, i))
1058  {
1059  dvalues[1] = (Datum) 0;
1060  nulls[1] = true;
1061  }
1062  else
1063  {
1064  item = cstring_to_text_with_len(HSTORE_VAL(entries, ptr, i),
1065  HSTORE_VALLEN(entries, i));
1066  dvalues[1] = PointerGetDatum(item);
1067  }
1068 
1069  tuple = heap_form_tuple(funcctx->tuple_desc, dvalues, nulls);
1070  res = HeapTupleGetDatum(tuple);
1071 
1072  SRF_RETURN_NEXT(funcctx, PointerGetDatum(res));
1073  }
1074 
1075  SRF_RETURN_DONE(funcctx);
1076 }
uint64 call_cntr
Definition: funcapi.h:65
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:282
#define PointerGetDatum(X)
Definition: postgres.h:556
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:286
TupleDesc tuple_desc
Definition: funcapi.h:112
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:288
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
static void setup_firstcall(FuncCallContext *funcctx, HStore *hs, FunctionCallInfo fcinfo)
Definition: hstore_op.c:855
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
uintptr_t Datum
Definition: postgres.h:367
Definition: hstore.h:18
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:220
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void * user_fctx
Definition: funcapi.h:82
#define STRPTR(x)
Definition: hstore.h:76
int i
Definition: c.h:556
#define ARRPTR(x)
Definition: cube.c:24
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:306
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:284

◆ hstore_eq()

Datum hstore_eq ( PG_FUNCTION_ARGS  )

Definition at line 1168 of file hstore_op.c.

References DatumGetInt32, DirectFunctionCall2, hstore_cmp(), hstore_ne(), PG_FUNCTION_INFO_V1(), PG_GETARG_DATUM, and PG_RETURN_BOOL.

Referenced by hstore_cmp().

1169 {
1171  PG_GETARG_DATUM(0),
1172  PG_GETARG_DATUM(1)));
1173 
1174  PG_RETURN_BOOL(res == 0);
1175 }
#define DatumGetInt32(X)
Definition: postgres.h:472
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum hstore_cmp(PG_FUNCTION_ARGS)
Definition: hstore_op.c:1087
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:617

◆ hstore_exists()

Datum hstore_exists ( PG_FUNCTION_ARGS  )

Definition at line 151 of file hstore_op.c.

References hstore_exists_any(), hstoreFindKey(), idx(), sort-test::key, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by hstore_fetchval().

152 {
153  HStore *hs = PG_GETARG_HSTORE_P(0);
154  text *key = PG_GETARG_TEXT_PP(1);
155  int idx = hstoreFindKey(hs, NULL,
156  VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
157 
158  PG_RETURN_BOOL(idx >= 0);
159 }
Definition: hstore.h:44
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:556

◆ hstore_exists_all()

Datum hstore_exists_all ( PG_FUNCTION_ARGS  )

Definition at line 198 of file hstore_op.c.

References hstore_defined(), hstoreArrayToPairs(), hstoreFindKey(), i, idx(), sort-test::key, PG_FUNCTION_INFO_V1(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_HSTORE_P, and PG_RETURN_BOOL.

Referenced by hstore_exists_any().

199 {
200  HStore *hs = PG_GETARG_HSTORE_P(0);
201  ArrayType *keys = PG_GETARG_ARRAYTYPE_P(1);
202  int nkeys;
203  Pairs *key_pairs = hstoreArrayToPairs(keys, &nkeys);
204  int i;
205  int lowbound = 0;
206  bool res = true;
207 
208  /*
209  * we exploit the fact that the pairs list is already sorted into strictly
210  * increasing order to narrow the hstoreFindKey search; each search can
211  * start one entry past the previous "found" entry, or at the lower bound
212  * of the last search.
213  */
214  for (i = 0; i < nkeys; i++)
215  {
216  int idx = hstoreFindKey(hs, &lowbound,
217  key_pairs[i].key, key_pairs[i].keylen);
218 
219  if (idx < 0)
220  {
221  res = false;
222  break;
223  }
224  }
225 
226  PG_RETURN_BOOL(res);
227 }
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Pairs * hstoreArrayToPairs(ArrayType *a, int *npairs)
Definition: hstore_op.c:73
int i
Definition: hstore.h:161

◆ hstore_exists_any()

Datum hstore_exists_any ( PG_FUNCTION_ARGS  )

Definition at line 164 of file hstore_op.c.

References hstore_exists_all(), hstoreArrayToPairs(), hstoreFindKey(), i, idx(), sort-test::key, PG_FUNCTION_INFO_V1(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_HSTORE_P, and PG_RETURN_BOOL.

Referenced by hstore_exists().

165 {
166  HStore *hs = PG_GETARG_HSTORE_P(0);
167  ArrayType *keys = PG_GETARG_ARRAYTYPE_P(1);
168  int nkeys;
169  Pairs *key_pairs = hstoreArrayToPairs(keys, &nkeys);
170  int i;
171  int lowbound = 0;
172  bool res = false;
173 
174  /*
175  * we exploit the fact that the pairs list is already sorted into strictly
176  * increasing order to narrow the hstoreFindKey search; each search can
177  * start one entry past the previous "found" entry, or at the lower bound
178  * of the last search.
179  */
180  for (i = 0; i < nkeys; i++)
181  {
182  int idx = hstoreFindKey(hs, &lowbound,
183  key_pairs[i].key, key_pairs[i].keylen);
184 
185  if (idx >= 0)
186  {
187  res = true;
188  break;
189  }
190  }
191 
192  PG_RETURN_BOOL(res);
193 }
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Pairs * hstoreArrayToPairs(ArrayType *a, int *npairs)
Definition: hstore_op.c:73
int i
Definition: hstore.h:161

◆ hstore_fetchval()

Datum hstore_fetchval ( PG_FUNCTION_ARGS  )

Definition at line 130 of file hstore_op.c.

References ARRPTR, cstring_to_text_with_len(), hstore_exists(), HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, hstoreFindKey(), idx(), sort-test::key, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_GETARG_TEXT_PP, PG_RETURN_NULL, PG_RETURN_TEXT_P, STRPTR, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by hstoreArrayToPairs().

131 {
132  HStore *hs = PG_GETARG_HSTORE_P(0);
133  text *key = PG_GETARG_TEXT_PP(1);
134  HEntry *entries = ARRPTR(hs);
135  text *out;
136  int idx = hstoreFindKey(hs, NULL,
137  VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key));
138 
139  if (idx < 0 || HSTORE_VALISNULL(entries, idx))
140  PG_RETURN_NULL();
141 
142  out = cstring_to_text_with_len(HSTORE_VAL(entries, STRPTR(hs), idx),
143  HSTORE_VALLEN(entries, idx));
144 
145  PG_RETURN_TEXT_P(out);
146 }
Definition: hstore.h:44
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define STRPTR(x)
Definition: hstore.h:76
Definition: c.h:556
#define ARRPTR(x)
Definition: cube.c:24
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ hstore_ge()

Datum hstore_ge ( PG_FUNCTION_ARGS  )

Definition at line 1201 of file hstore_op.c.

References DatumGetInt32, DirectFunctionCall2, hstore_cmp(), hstore_lt(), PG_FUNCTION_INFO_V1(), PG_GETARG_DATUM, and PG_RETURN_BOOL.

Referenced by hstore_gt().

1202 {
1204  PG_GETARG_DATUM(0),
1205  PG_GETARG_DATUM(1)));
1206 
1207  PG_RETURN_BOOL(res >= 0);
1208 }
#define DatumGetInt32(X)
Definition: postgres.h:472
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum hstore_cmp(PG_FUNCTION_ARGS)
Definition: hstore_op.c:1087
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:617

◆ hstore_gt()

Datum hstore_gt ( PG_FUNCTION_ARGS  )

Definition at line 1190 of file hstore_op.c.

References DatumGetInt32, DirectFunctionCall2, hstore_cmp(), hstore_ge(), PG_FUNCTION_INFO_V1(), PG_GETARG_DATUM, and PG_RETURN_BOOL.

Referenced by hstore_ne().

1191 {
1193  PG_GETARG_DATUM(0),
1194  PG_GETARG_DATUM(1)));
1195 
1196  PG_RETURN_BOOL(res > 0);
1197 }
#define DatumGetInt32(X)
Definition: postgres.h:472
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum hstore_cmp(PG_FUNCTION_ARGS)
Definition: hstore_op.c:1087
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:617

◆ hstore_hash()

Datum hstore_hash ( PG_FUNCTION_ARGS  )

Definition at line 1235 of file hstore_op.c.

References ARRPTR, Assert, CALCDATASIZE, hash_any(), HS_COUNT, HSE_ENDPOS, HSHRDSIZE, hstore_hash_extended(), PG_FREE_IF_COPY, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_DATUM, VARDATA, VARHDRSZ, and VARSIZE.

Referenced by hstore_le().

1236 {
1237  HStore *hs = PG_GETARG_HSTORE_P(0);
1238  Datum hval = hash_any((unsigned char *) VARDATA(hs),
1239  VARSIZE(hs) - VARHDRSZ);
1240 
1241  /*
1242  * This (along with hstore_hash_extended) is the only place in the code
1243  * that cares whether the overall varlena size exactly matches the true
1244  * data size; this assertion should be maintained by all the other code,
1245  * but we make it explicit here.
1246  */
1247  Assert(VARSIZE(hs) ==
1248  (HS_COUNT(hs) != 0 ?
1249  CALCDATASIZE(HS_COUNT(hs),
1250  HSE_ENDPOS(ARRPTR(hs)[2 * HS_COUNT(hs) - 1])) :
1251  HSHRDSIZE));
1252 
1253  PG_FREE_IF_COPY(hs, 0);
1254  PG_RETURN_DATUM(hval);
1255 }
#define HSE_ENDPOS(he_)
Definition: hstore.h:30
Definition: hstore.h:44
#define VARDATA(PTR)
Definition: postgres.h:302
Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.c:148
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:562
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define HSHRDSIZE
Definition: hstore.h:71
#define Assert(condition)
Definition: c.h:739
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define ARRPTR(x)
Definition: cube.c:24

◆ hstore_hash_extended()

Datum hstore_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 1259 of file hstore_op.c.

References ARRPTR, Assert, CALCDATASIZE, hash_any_extended(), HS_COUNT, HSE_ENDPOS, HSHRDSIZE, PG_FREE_IF_COPY, PG_GETARG_HSTORE_P, PG_GETARG_INT64, PG_RETURN_DATUM, VARDATA, VARHDRSZ, and VARSIZE.

Referenced by hstore_hash().

1260 {
1261  HStore *hs = PG_GETARG_HSTORE_P(0);
1262  uint64 seed = PG_GETARG_INT64(1);
1263  Datum hval;
1264 
1265  hval = hash_any_extended((unsigned char *) VARDATA(hs),
1266  VARSIZE(hs) - VARHDRSZ,
1267  seed);
1268 
1269  /* See comment in hstore_hash */
1270  Assert(VARSIZE(hs) ==
1271  (HS_COUNT(hs) != 0 ?
1272  CALCDATASIZE(HS_COUNT(hs),
1273  HSE_ENDPOS(ARRPTR(hs)[2 * HS_COUNT(hs) - 1])) :
1274  HSHRDSIZE));
1275 
1276  PG_FREE_IF_COPY(hs, 0);
1277  PG_RETURN_DATUM(hval);
1278 }
#define HSE_ENDPOS(he_)
Definition: hstore.h:30
Definition: hstore.h:44
#define VARDATA(PTR)
Definition: postgres.h:302
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:562
Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition: hashfn.c:374
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define HSHRDSIZE
Definition: hstore.h:71
#define Assert(condition)
Definition: c.h:739
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define ARRPTR(x)
Definition: cube.c:24
#define PG_GETARG_INT64(n)
Definition: fmgr.h:277

◆ hstore_le()

Datum hstore_le ( PG_FUNCTION_ARGS  )

Definition at line 1223 of file hstore_op.c.

References DatumGetInt32, DirectFunctionCall2, hstore_cmp(), hstore_hash(), PG_FUNCTION_INFO_V1(), PG_GETARG_DATUM, and PG_RETURN_BOOL.

Referenced by hstore_lt().

1224 {
1226  PG_GETARG_DATUM(0),
1227  PG_GETARG_DATUM(1)));
1228 
1229  PG_RETURN_BOOL(res <= 0);
1230 }
#define DatumGetInt32(X)
Definition: postgres.h:472
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum hstore_cmp(PG_FUNCTION_ARGS)
Definition: hstore_op.c:1087
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:617

◆ hstore_lt()

Datum hstore_lt ( PG_FUNCTION_ARGS  )

Definition at line 1212 of file hstore_op.c.

References DatumGetInt32, DirectFunctionCall2, hstore_cmp(), hstore_le(), PG_FUNCTION_INFO_V1(), PG_GETARG_DATUM, and PG_RETURN_BOOL.

Referenced by hstore_ge().

1213 {
1215  PG_GETARG_DATUM(0),
1216  PG_GETARG_DATUM(1)));
1217 
1218  PG_RETURN_BOOL(res < 0);
1219 }
#define DatumGetInt32(X)
Definition: postgres.h:472
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum hstore_cmp(PG_FUNCTION_ARGS)
Definition: hstore_op.c:1087
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:617

◆ hstore_ne()

Datum hstore_ne ( PG_FUNCTION_ARGS  )

Definition at line 1179 of file hstore_op.c.

References DatumGetInt32, DirectFunctionCall2, hstore_cmp(), hstore_gt(), PG_FUNCTION_INFO_V1(), PG_GETARG_DATUM, and PG_RETURN_BOOL.

Referenced by hstore_eq().

1180 {
1182  PG_GETARG_DATUM(0),
1183  PG_GETARG_DATUM(1)));
1184 
1185  PG_RETURN_BOOL(res != 0);
1186 }
#define DatumGetInt32(X)
Definition: postgres.h:472
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum hstore_cmp(PG_FUNCTION_ARGS)
Definition: hstore_op.c:1087
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:617

◆ HSTORE_POLLUTE() [1/12]

HSTORE_POLLUTE ( hstore_fetchval  ,
fetchval   
)

◆ HSTORE_POLLUTE() [2/12]

HSTORE_POLLUTE ( hstore_exists  ,
exists   
)

◆ HSTORE_POLLUTE() [3/12]

HSTORE_POLLUTE ( hstore_defined  ,
defined   
)

◆ HSTORE_POLLUTE() [4/12]

HSTORE_POLLUTE ( hstore_delete  ,
delete   
)

◆ HSTORE_POLLUTE() [5/12]

HSTORE_POLLUTE ( hstore_concat  ,
hs_concat   
)

◆ HSTORE_POLLUTE() [6/12]

HSTORE_POLLUTE ( hstore_contains  ,
hs_contains   
)

◆ HSTORE_POLLUTE() [7/12]

HSTORE_POLLUTE ( hstore_contained  ,
hs_contained   
)

◆ HSTORE_POLLUTE() [8/12]

HSTORE_POLLUTE ( hstore_akeys  ,
akeys   
)

◆ HSTORE_POLLUTE() [9/12]

HSTORE_POLLUTE ( hstore_avals  ,
avals   
)

◆ HSTORE_POLLUTE() [10/12]

HSTORE_POLLUTE ( hstore_skeys  ,
skeys   
)

◆ HSTORE_POLLUTE() [11/12]

HSTORE_POLLUTE ( hstore_svals  ,
svals   
)

◆ HSTORE_POLLUTE() [12/12]

HSTORE_POLLUTE ( hstore_each  ,
each   
)

◆ hstore_skeys()

Datum hstore_skeys ( PG_FUNCTION_ARGS  )

Definition at line 885 of file hstore_op.c.

References ARRPTR, FuncCallContext::call_cntr, cstring_to_text_with_len(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, hstore_svals(), i, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PointerGetDatum, setup_firstcall(), SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, STRPTR, and FuncCallContext::user_fctx.

Referenced by setup_firstcall().

886 {
887  FuncCallContext *funcctx;
888  HStore *hs;
889  int i;
890 
891  if (SRF_IS_FIRSTCALL())
892  {
893  hs = PG_GETARG_HSTORE_P(0);
894  funcctx = SRF_FIRSTCALL_INIT();
895  setup_firstcall(funcctx, hs, NULL);
896  }
897 
898  funcctx = SRF_PERCALL_SETUP();
899  hs = (HStore *) funcctx->user_fctx;
900  i = funcctx->call_cntr;
901 
902  if (i < HS_COUNT(hs))
903  {
904  HEntry *entries = ARRPTR(hs);
905  text *item;
906 
907  item = cstring_to_text_with_len(HSTORE_KEY(entries, STRPTR(hs), i),
908  HSTORE_KEYLEN(entries, i));
909 
910  SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
911  }
912 
913  SRF_RETURN_DONE(funcctx);
914 }
uint64 call_cntr
Definition: funcapi.h:65
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:282
#define PointerGetDatum(X)
Definition: postgres.h:556
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:286
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:288
static void setup_firstcall(FuncCallContext *funcctx, HStore *hs, FunctionCallInfo fcinfo)
Definition: hstore_op.c:855
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
Definition: hstore.h:18
void * user_fctx
Definition: funcapi.h:82
#define STRPTR(x)
Definition: hstore.h:76
int i
Definition: c.h:556
#define ARRPTR(x)
Definition: cube.c:24
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:306
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:284

◆ hstore_slice_to_array()

Datum hstore_slice_to_array ( PG_FUNCTION_ARGS  )

Definition at line 571 of file hstore_op.c.

References ARR_DIMS, ARR_LBOUND, ARR_NDIM, ARRPTR, construct_empty_array(), construct_md_array(), cstring_to_text_with_len(), DatumGetPointer, deconstruct_array(), hstore_slice_to_hstore(), HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, hstoreFindKey(), i, idx(), sort-test::key, palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_HSTORE_P, PG_RETURN_POINTER, PointerGetDatum, STRPTR, VARDATA, VARHDRSZ, and VARSIZE.

Referenced by hstore_concat().

572 {
573  HStore *hs = PG_GETARG_HSTORE_P(0);
574  HEntry *entries = ARRPTR(hs);
575  char *ptr = STRPTR(hs);
576  ArrayType *key_array = PG_GETARG_ARRAYTYPE_P(1);
577  ArrayType *aout;
578  Datum *key_datums;
579  bool *key_nulls;
580  Datum *out_datums;
581  bool *out_nulls;
582  int key_count;
583  int i;
584 
585  deconstruct_array(key_array,
586  TEXTOID, -1, false, 'i',
587  &key_datums, &key_nulls, &key_count);
588 
589  if (key_count == 0)
590  {
591  aout = construct_empty_array(TEXTOID);
592  PG_RETURN_POINTER(aout);
593  }
594 
595  out_datums = palloc(sizeof(Datum) * key_count);
596  out_nulls = palloc(sizeof(bool) * key_count);
597 
598  for (i = 0; i < key_count; ++i)
599  {
600  text *key = (text *) DatumGetPointer(key_datums[i]);
601  int idx;
602 
603  if (key_nulls[i])
604  idx = -1;
605  else
606  idx = hstoreFindKey(hs, NULL, VARDATA(key), VARSIZE(key) - VARHDRSZ);
607 
608  if (idx < 0 || HSTORE_VALISNULL(entries, idx))
609  {
610  out_nulls[i] = true;
611  out_datums[i] = (Datum) 0;
612  }
613  else
614  {
615  out_datums[i] = PointerGetDatum(
616  cstring_to_text_with_len(HSTORE_VAL(entries, ptr, idx),
617  HSTORE_VALLEN(entries, idx)));
618  out_nulls[i] = false;
619  }
620  }
621 
622  aout = construct_md_array(out_datums, out_nulls,
623  ARR_NDIM(key_array),
624  ARR_DIMS(key_array),
625  ARR_LBOUND(key_array),
626  TEXTOID, -1, false, 'i');
627 
628  PG_RETURN_POINTER(aout);
629 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define VARDATA(PTR)
Definition: postgres.h:302
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define VARSIZE(PTR)
Definition: postgres.h:303
#define PointerGetDatum(X)
Definition: postgres.h:556
#define VARHDRSZ
Definition: c.h:562
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3410
#define ARR_LBOUND(a)
Definition: array.h:284
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define ARR_DIMS(a)
Definition: array.h:282
int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
uintptr_t Datum
Definition: postgres.h:367
Definition: hstore.h:18
#define ARR_NDIM(a)
Definition: array.h:278
#define DatumGetPointer(X)
Definition: postgres.h:549
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3461
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
Definition: c.h:556
#define ARRPTR(x)
Definition: cube.c:24
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3326

◆ hstore_slice_to_hstore()

Datum hstore_slice_to_hstore ( PG_FUNCTION_ARGS  )

Definition at line 634 of file hstore_op.c.

References ARRPTR, hstore_akeys(), HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, hstoreArrayToPairs(), hstoreFindKey(), hstorePairs, i, idx(), Pairs::isnull, sort-test::key, Pairs::key, Pairs::keylen, Pairs::needfree, palloc(), PG_FUNCTION_INFO_V1(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_HSTORE_P, PG_RETURN_POINTER, STRPTR, Pairs::val, and Pairs::vallen.

Referenced by hstore_slice_to_array().

635 {
636  HStore *hs = PG_GETARG_HSTORE_P(0);
637  HEntry *entries = ARRPTR(hs);
638  char *ptr = STRPTR(hs);
639  ArrayType *key_array = PG_GETARG_ARRAYTYPE_P(1);
640  HStore *out;
641  int nkeys;
642  Pairs *key_pairs = hstoreArrayToPairs(key_array, &nkeys);
643  Pairs *out_pairs;
644  int bufsiz;
645  int lastidx = 0;
646  int i;
647  int out_count = 0;
648 
649  if (nkeys == 0)
650  {
651  out = hstorePairs(NULL, 0, 0);
652  PG_RETURN_POINTER(out);
653  }
654 
655  /* hstoreArrayToPairs() checked overflow */
656  out_pairs = palloc(sizeof(Pairs) * nkeys);
657  bufsiz = 0;
658 
659  /*
660  * we exploit the fact that the pairs list is already sorted into strictly
661  * increasing order to narrow the hstoreFindKey search; each search can
662  * start one entry past the previous "found" entry, or at the lower bound
663  * of the last search.
664  */
665 
666  for (i = 0; i < nkeys; ++i)
667  {
668  int idx = hstoreFindKey(hs, &lastidx,
669  key_pairs[i].key, key_pairs[i].keylen);
670 
671  if (idx >= 0)
672  {
673  out_pairs[out_count].key = key_pairs[i].key;
674  bufsiz += (out_pairs[out_count].keylen = key_pairs[i].keylen);
675  out_pairs[out_count].val = HSTORE_VAL(entries, ptr, idx);
676  bufsiz += (out_pairs[out_count].vallen = HSTORE_VALLEN(entries, idx));
677  out_pairs[out_count].isnull = HSTORE_VALISNULL(entries, idx);
678  out_pairs[out_count].needfree = false;
679  ++out_count;
680  }
681  }
682 
683  /*
684  * we don't use hstoreUniquePairs here because we know that the pairs list
685  * is already sorted and uniq'ed.
686  */
687 
688  out = hstorePairs(out_pairs, out_count, bufsiz);
689 
690  PG_RETURN_POINTER(out);
691 }
#define hstorePairs
Definition: hstore_plperl.c:58
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
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 PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
Pairs * hstoreArrayToPairs(ArrayType *a, int *npairs)
Definition: hstore_op.c:73
size_t keylen
Definition: hstore.h:165
bool isnull
Definition: hstore.h:167
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
#define ARRPTR(x)
Definition: cube.c:24
Definition: hstore.h:161

◆ hstore_svals()

Datum hstore_svals ( PG_FUNCTION_ARGS  )

Definition at line 919 of file hstore_op.c.

References ARRPTR, FuncCallContext::call_cntr, cstring_to_text_with_len(), ExprMultipleResult, HS_COUNT, hstore_contains(), HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, ReturnSetInfo::isDone, PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, PG_RETURN_NULL, PointerGetDatum, setup_firstcall(), SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, STRPTR, and FuncCallContext::user_fctx.

Referenced by hstore_skeys().

920 {
921  FuncCallContext *funcctx;
922  HStore *hs;
923  int i;
924 
925  if (SRF_IS_FIRSTCALL())
926  {
927  hs = PG_GETARG_HSTORE_P(0);
928  funcctx = SRF_FIRSTCALL_INIT();
929  setup_firstcall(funcctx, hs, NULL);
930  }
931 
932  funcctx = SRF_PERCALL_SETUP();
933  hs = (HStore *) funcctx->user_fctx;
934  i = funcctx->call_cntr;
935 
936  if (i < HS_COUNT(hs))
937  {
938  HEntry *entries = ARRPTR(hs);
939 
940  if (HSTORE_VALISNULL(entries, i))
941  {
942  ReturnSetInfo *rsi;
943 
944  /* ugly ugly ugly. why no macro for this? */
945  (funcctx)->call_cntr++;
946  rsi = (ReturnSetInfo *) fcinfo->resultinfo;
947  rsi->isDone = ExprMultipleResult;
948  PG_RETURN_NULL();
949  }
950  else
951  {
952  text *item;
953 
954  item = cstring_to_text_with_len(HSTORE_VAL(entries, STRPTR(hs), i),
955  HSTORE_VALLEN(entries, i));
956 
957  SRF_RETURN_NEXT(funcctx, PointerGetDatum(item));
958  }
959  }
960 
961  SRF_RETURN_DONE(funcctx);
962 }
uint64 call_cntr
Definition: funcapi.h:65
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:282
#define PointerGetDatum(X)
Definition: postgres.h:556
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:286
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:288
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
static void setup_firstcall(FuncCallContext *funcctx, HStore *hs, FunctionCallInfo fcinfo)
Definition: hstore_op.c:855
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define HS_COUNT(hsp_)
Definition: hstore.h:61
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void * user_fctx
Definition: funcapi.h:82
#define STRPTR(x)
Definition: hstore.h:76
int i
Definition: c.h:556
#define ARRPTR(x)
Definition: cube.c:24
ExprDoneCond isDone
Definition: execnodes.h:305
#define PG_RETURN_NULL()
Definition: fmgr.h:335
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:306
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:284

◆ hstore_to_array()

Datum hstore_to_array ( PG_FUNCTION_ARGS  )

Definition at line 827 of file hstore_op.c.

References hstore_to_array_internal(), hstore_to_matrix(), PG_FUNCTION_INFO_V1(), PG_GETARG_HSTORE_P, and PG_RETURN_POINTER.

Referenced by hstore_to_array_internal().

828 {
829  HStore *hs = PG_GETARG_HSTORE_P(0);
830  ArrayType *out = hstore_to_array_internal(hs, 1);
831 
832  PG_RETURN_POINTER(out);
833 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
static ArrayType * hstore_to_array_internal(HStore *hs, int ndims)
Definition: hstore_op.c:777

◆ hstore_to_array_internal()

static ArrayType* hstore_to_array_internal ( HStore hs,
int  ndims 
)
static

Definition at line 777 of file hstore_op.c.

References ARRPTR, Assert, construct_empty_array(), construct_md_array(), cstring_to_text_with_len(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, hstore_to_array(), HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, sort-test::key, palloc(), PG_FUNCTION_INFO_V1(), PointerGetDatum, and STRPTR.

Referenced by hstore_to_array(), and hstore_to_matrix().

778 {
779  HEntry *entries = ARRPTR(hs);
780  char *base = STRPTR(hs);
781  int count = HS_COUNT(hs);
782  int out_size[2] = {0, 2};
783  int lb[2] = {1, 1};
784  Datum *out_datums;
785  bool *out_nulls;
786  int i;
787 
788  Assert(ndims < 3);
789 
790  if (count == 0 || ndims == 0)
791  return construct_empty_array(TEXTOID);
792 
793  out_size[0] = count * 2 / ndims;
794  out_datums = palloc(sizeof(Datum) * count * 2);
795  out_nulls = palloc(sizeof(bool) * count * 2);
796 
797  for (i = 0; i < count; ++i)
798  {
799  text *key = cstring_to_text_with_len(HSTORE_KEY(entries, base, i),
800  HSTORE_KEYLEN(entries, i));
801 
802  out_datums[i * 2] = PointerGetDatum(key);
803  out_nulls[i * 2] = false;
804 
805  if (HSTORE_VALISNULL(entries, i))
806  {
807  out_datums[i * 2 + 1] = (Datum) 0;
808  out_nulls[i * 2 + 1] = true;
809  }
810  else
811  {
812  text *item = cstring_to_text_with_len(HSTORE_VAL(entries, base, i),
813  HSTORE_VALLEN(entries, i));
814 
815  out_datums[i * 2 + 1] = PointerGetDatum(item);
816  out_nulls[i * 2 + 1] = false;
817  }
818  }
819 
820  return construct_md_array(out_datums, out_nulls,
821  ndims, out_size, lb,
822  TEXTOID, -1, false, 'i');
823 }
#define PointerGetDatum(X)
Definition: postgres.h:556
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3410
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
uintptr_t Datum
Definition: postgres.h:367
#define Assert(condition)
Definition: c.h:739
Definition: hstore.h:18
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
void * palloc(Size size)
Definition: mcxt.c:949
#define STRPTR(x)
Definition: hstore.h:76
int i
Definition: c.h:556
#define ARRPTR(x)
Definition: cube.c:24
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3326

◆ hstore_to_matrix()

Datum hstore_to_matrix ( PG_FUNCTION_ARGS  )

Definition at line 837 of file hstore_op.c.

References hstore_to_array_internal(), PG_GETARG_HSTORE_P, and PG_RETURN_POINTER.

Referenced by hstore_to_array().

838 {
839  HStore *hs = PG_GETARG_HSTORE_P(0);
840  ArrayType *out = hstore_to_array_internal(hs, 2);
841 
842  PG_RETURN_POINTER(out);
843 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
Definition: hstore.h:44
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
static ArrayType * hstore_to_array_internal(HStore *hs, int ndims)
Definition: hstore_op.c:777

◆ hstoreArrayToPairs()

Pairs* hstoreArrayToPairs ( ArrayType a,
int *  npairs 
)

Definition at line 73 of file hstore_op.c.

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

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

74 {
75  Datum *key_datums;
76  bool *key_nulls;
77  int key_count;
78  Pairs *key_pairs;
79  int bufsiz;
80  int i,
81  j;
82 
84  TEXTOID, -1, false, 'i',
85  &key_datums, &key_nulls, &key_count);
86 
87  if (key_count == 0)
88  {
89  *npairs = 0;
90  return NULL;
91  }
92 
93  /*
94  * A text array uses at least eight bytes per element, so any overflow in
95  * "key_count * sizeof(Pairs)" is small enough for palloc() to catch.
96  * However, credible improvements to the array format could invalidate
97  * that assumption. Therefore, use an explicit check rather than relying
98  * on palloc() to complain.
99  */
100  if (key_count > MaxAllocSize / sizeof(Pairs))
101  ereport(ERROR,
102  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
103  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
104  key_count, (int) (MaxAllocSize / sizeof(Pairs)))));
105 
106  key_pairs = palloc(sizeof(Pairs) * key_count);
107 
108  for (i = 0, j = 0; i < key_count; i++)
109  {
110  if (!key_nulls[i])
111  {
112  key_pairs[j].key = VARDATA(key_datums[i]);
113  key_pairs[j].keylen = VARSIZE(key_datums[i]) - VARHDRSZ;
114  key_pairs[j].val = NULL;
115  key_pairs[j].vallen = 0;
116  key_pairs[j].needfree = 0;
117  key_pairs[j].isnull = 1;
118  j++;
119  }
120  }
121 
122  *npairs = hstoreUniquePairs(key_pairs, j, &bufsiz);
123 
124  return key_pairs;
125 }
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:562
int errcode(int sqlerrcode)
Definition: elog.c:608
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:141
#define MaxAllocSize
Definition: memutils.h:40
#define hstoreUniquePairs
Definition: hstore_plperl.c:57
uintptr_t Datum
Definition: postgres.h:367
size_t keylen
Definition: hstore.h:165
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:3461
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
int i
Definition: hstore.h:161

◆ hstoreFindKey()

int hstoreFindKey ( HStore hs,
int *  lowbound,
char *  key,
int  keylen 
)

Definition at line 36 of file hstore_op.c.

References ARRPTR, difference(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, sort-test::key, 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().

37 {
38  HEntry *entries = ARRPTR(hs);
39  int stopLow = lowbound ? *lowbound : 0;
40  int stopHigh = HS_COUNT(hs);
41  int stopMiddle;
42  char *base = STRPTR(hs);
43 
44  while (stopLow < stopHigh)
45  {
46  int difference;
47 
48  stopMiddle = stopLow + (stopHigh - stopLow) / 2;
49 
50  if (HSTORE_KEYLEN(entries, stopMiddle) == keylen)
51  difference = memcmp(HSTORE_KEY(entries, base, stopMiddle), key, keylen);
52  else
53  difference = (HSTORE_KEYLEN(entries, stopMiddle) > keylen) ? 1 : -1;
54 
55  if (difference == 0)
56  {
57  if (lowbound)
58  *lowbound = stopMiddle + 1;
59  return stopMiddle;
60  }
61  else if (difference < 0)
62  stopLow = stopMiddle + 1;
63  else
64  stopHigh = stopMiddle;
65  }
66 
67  if (lowbound)
68  *lowbound = stopLow;
69  return -1;
70 }
#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:24

◆ PG_FUNCTION_INFO_V1() [1/29]

◆ PG_FUNCTION_INFO_V1() [2/29]

PG_FUNCTION_INFO_V1 ( hstore_exists  )

◆ PG_FUNCTION_INFO_V1() [3/29]

PG_FUNCTION_INFO_V1 ( hstore_exists_any  )

◆ PG_FUNCTION_INFO_V1() [4/29]

PG_FUNCTION_INFO_V1 ( hstore_exists_all  )

◆ PG_FUNCTION_INFO_V1() [5/29]

PG_FUNCTION_INFO_V1 ( hstore_defined  )

◆ PG_FUNCTION_INFO_V1() [6/29]

PG_FUNCTION_INFO_V1 ( hstore_delete  )

◆ PG_FUNCTION_INFO_V1() [7/29]

PG_FUNCTION_INFO_V1 ( hstore_delete_array  )

◆ PG_FUNCTION_INFO_V1() [8/29]

PG_FUNCTION_INFO_V1 ( hstore_delete_hstore  )

◆ PG_FUNCTION_INFO_V1() [9/29]

PG_FUNCTION_INFO_V1 ( hstore_concat  )

◆ PG_FUNCTION_INFO_V1() [10/29]

PG_FUNCTION_INFO_V1 ( hstore_slice_to_array  )

◆ PG_FUNCTION_INFO_V1() [11/29]

PG_FUNCTION_INFO_V1 ( hstore_slice_to_hstore  )

◆ PG_FUNCTION_INFO_V1() [12/29]

PG_FUNCTION_INFO_V1 ( hstore_akeys  )

◆ PG_FUNCTION_INFO_V1() [13/29]

PG_FUNCTION_INFO_V1 ( hstore_avals  )

◆ PG_FUNCTION_INFO_V1() [14/29]

PG_FUNCTION_INFO_V1 ( hstore_to_array  )

◆ PG_FUNCTION_INFO_V1() [15/29]

PG_FUNCTION_INFO_V1 ( hstore_to_matrix  )

◆ PG_FUNCTION_INFO_V1() [16/29]

PG_FUNCTION_INFO_V1 ( hstore_skeys  )

◆ PG_FUNCTION_INFO_V1() [17/29]

PG_FUNCTION_INFO_V1 ( hstore_svals  )

◆ PG_FUNCTION_INFO_V1() [18/29]

PG_FUNCTION_INFO_V1 ( hstore_contains  )

◆ PG_FUNCTION_INFO_V1() [19/29]

PG_FUNCTION_INFO_V1 ( hstore_contained  )

◆ PG_FUNCTION_INFO_V1() [20/29]

PG_FUNCTION_INFO_V1 ( hstore_each  )

◆ PG_FUNCTION_INFO_V1() [21/29]

PG_FUNCTION_INFO_V1 ( hstore_cmp  )

◆ PG_FUNCTION_INFO_V1() [22/29]

PG_FUNCTION_INFO_V1 ( hstore_eq  )

◆ PG_FUNCTION_INFO_V1() [23/29]

PG_FUNCTION_INFO_V1 ( hstore_ne  )

◆ PG_FUNCTION_INFO_V1() [24/29]

PG_FUNCTION_INFO_V1 ( hstore_gt  )

◆ PG_FUNCTION_INFO_V1() [25/29]

PG_FUNCTION_INFO_V1 ( hstore_ge  )

◆ PG_FUNCTION_INFO_V1() [26/29]

PG_FUNCTION_INFO_V1 ( hstore_lt  )

◆ PG_FUNCTION_INFO_V1() [27/29]

PG_FUNCTION_INFO_V1 ( hstore_le  )

◆ PG_FUNCTION_INFO_V1() [28/29]

PG_FUNCTION_INFO_V1 ( hstore_hash  )

◆ PG_FUNCTION_INFO_V1() [29/29]

PG_FUNCTION_INFO_V1 ( hstore_hash_extended  )

◆ setup_firstcall()

static void setup_firstcall ( FuncCallContext funcctx,
HStore hs,
FunctionCallInfo  fcinfo 
)
static

Definition at line 855 of file hstore_op.c.

References BlessTupleDesc(), elog, ERROR, get_call_result_type(), hstore_skeys(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, palloc(), PG_FUNCTION_INFO_V1(), FuncCallContext::tuple_desc, TYPEFUNC_COMPOSITE, FuncCallContext::user_fctx, and VARSIZE.

Referenced by hstore_each(), hstore_skeys(), and hstore_svals().

857 {
858  MemoryContext oldcontext;
859  HStore *st;
860 
861  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
862 
863  st = (HStore *) palloc(VARSIZE(hs));
864  memcpy(st, hs, VARSIZE(hs));
865 
866  funcctx->user_fctx = (void *) st;
867 
868  if (fcinfo)
869  {
870  TupleDesc tupdesc;
871 
872  /* Build a tuple descriptor for our result type */
873  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
874  elog(ERROR, "return type must be a row type");
875 
876  funcctx->tuple_desc = BlessTupleDesc(tupdesc);
877  }
878 
879  MemoryContextSwitchTo(oldcontext);
880 }
Definition: hstore.h:44
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:196
#define VARSIZE(PTR)
Definition: postgres.h:303
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
TupleDesc tuple_desc
Definition: funcapi.h:112
#define ERROR
Definition: elog.h:43
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2052
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
void * user_fctx
Definition: funcapi.h:82
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:228