PostgreSQL Source Code  git master
hstore_io.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "access/htup_details.h"
#include "catalog/pg_type.h"
#include "common/jsonapi.h"
#include "funcapi.h"
#include "hstore.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "nodes/miscnodes.h"
#include "utils/builtins.h"
#include "utils/json.h"
#include "utils/jsonb.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/typcache.h"
Include dependency graph for hstore_io.c:

Go to the source code of this file.

Data Structures

struct  HSParser
 
struct  ColumnIOData
 
struct  RecordIOData
 

Macros

#define RESIZEPRSBUF
 
#define PRSSYNTAXERROR   return prssyntaxerror(state)
 
#define PRSEOF   return prseof(state)
 
#define GV_WAITVAL   0
 
#define GV_INVAL   1
 
#define GV_INESCVAL   2
 
#define GV_WAITESCIN   3
 
#define GV_WAITESCESCIN   4
 
#define WKEY   0
 
#define WVAL   1
 
#define WEQ   2
 
#define WGT   3
 
#define WDEL   4
 

Typedefs

typedef struct ColumnIOData ColumnIOData
 
typedef struct RecordIOData RecordIOData
 

Functions

 HSTORE_POLLUTE (hstore_from_text, tconvert)
 
static bool hstoreCheckKeyLength (size_t len, HSParser *state)
 
static bool hstoreCheckValLength (size_t len, HSParser *state)
 
static bool prssyntaxerror (HSParser *state)
 
static bool prseof (HSParser *state)
 
static bool get_val (HSParser *state, bool ignoreeq, bool *escaped)
 
static bool parse_hstore (HSParser *state)
 
static int comparePairs (const void *a, const void *b)
 
int hstoreUniquePairs (Pairs *a, int32 l, int32 *buflen)
 
size_t hstoreCheckKeyLen (size_t len)
 
size_t hstoreCheckValLen (size_t len)
 
HStorehstorePairs (Pairs *pairs, int32 pcount, int32 buflen)
 
 PG_FUNCTION_INFO_V1 (hstore_in)
 
Datum hstore_in (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_recv)
 
Datum hstore_recv (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_from_text)
 
Datum hstore_from_text (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_from_arrays)
 
Datum hstore_from_arrays (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_from_array)
 
Datum hstore_from_array (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_from_record)
 
Datum hstore_from_record (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_populate_record)
 
Datum hstore_populate_record (PG_FUNCTION_ARGS)
 
static char * cpw (char *dst, char *src, int len)
 
 PG_FUNCTION_INFO_V1 (hstore_out)
 
Datum hstore_out (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_send)
 
Datum hstore_send (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_to_json_loose)
 
Datum hstore_to_json_loose (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_to_json)
 
Datum hstore_to_json (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_to_jsonb)
 
Datum hstore_to_jsonb (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (hstore_to_jsonb_loose)
 
Datum hstore_to_jsonb_loose (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 

Macro Definition Documentation

◆ GV_INESCVAL

#define GV_INESCVAL   2

Definition at line 87 of file hstore_io.c.

◆ GV_INVAL

#define GV_INVAL   1

Definition at line 86 of file hstore_io.c.

◆ GV_WAITESCESCIN

#define GV_WAITESCESCIN   4

Definition at line 89 of file hstore_io.c.

◆ GV_WAITESCIN

#define GV_WAITESCIN   3

Definition at line 88 of file hstore_io.c.

◆ GV_WAITVAL

#define GV_WAITVAL   0

Definition at line 85 of file hstore_io.c.

◆ PRSEOF

#define PRSEOF   return prseof(state)

Definition at line 72 of file hstore_io.c.

◆ PRSSYNTAXERROR

#define PRSSYNTAXERROR   return prssyntaxerror(state)

Definition at line 58 of file hstore_io.c.

◆ RESIZEPRSBUF

#define RESIZEPRSBUF
Value:
do { \
if ( state->cur - state->word + 1 >= state->wordlen ) \
{ \
int32 clen = state->cur - state->word; \
state->wordlen *= 2; \
state->word = (char*)repalloc( (void*)state->word, state->wordlen ); \
state->cur = state->word + clen; \
} \
} while (0)
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1476
Definition: regguts.h:323

Definition at line 47 of file hstore_io.c.

◆ WDEL

#define WDEL   4

Definition at line 210 of file hstore_io.c.

◆ WEQ

#define WEQ   2

Definition at line 208 of file hstore_io.c.

◆ WGT

#define WGT   3

Definition at line 209 of file hstore_io.c.

◆ WKEY

#define WKEY   0

Definition at line 206 of file hstore_io.c.

◆ WVAL

#define WVAL   1

Definition at line 207 of file hstore_io.c.

Typedef Documentation

◆ ColumnIOData

typedef struct ColumnIOData ColumnIOData

◆ RecordIOData

typedef struct RecordIOData RecordIOData

Function Documentation

◆ comparePairs()

static int comparePairs ( const void *  a,
const void *  b 
)
static

Definition at line 325 of file hstore_io.c.

326 {
327  const Pairs *pa = a;
328  const Pairs *pb = b;
329 
330  if (pa->keylen == pb->keylen)
331  {
332  int res = memcmp(pa->key, pb->key, pa->keylen);
333 
334  if (res)
335  return res;
336 
337  /* guarantee that needfree will be later */
338  if (pb->needfree == pa->needfree)
339  return 0;
340  else if (pa->needfree)
341  return 1;
342  else
343  return -1;
344  }
345  return (pa->keylen > pb->keylen) ? 1 : -1;
346 }
int b
Definition: isn.c:70
int a
Definition: isn.c:69
Definition: hstore.h:162
size_t keylen
Definition: hstore.h:165
char * key
Definition: hstore.h:163
bool needfree
Definition: hstore.h:168

References a, b, Pairs::key, Pairs::keylen, Pairs::needfree, and res.

Referenced by hstoreUniquePairs().

◆ cpw()

static char* cpw ( char *  dst,
char *  src,
int  len 
)
static

Definition at line 1206 of file hstore_io.c.

1207 {
1208  char *ptr = src;
1209 
1210  while (ptr - src < len)
1211  {
1212  if (*ptr == '"' || *ptr == '\\')
1213  *dst++ = '\\';
1214  *dst++ = *ptr++;
1215  }
1216  return dst;
1217 }
const void size_t len

References len.

Referenced by hstore_out().

◆ get_val()

static bool get_val ( HSParser state,
bool  ignoreeq,
bool escaped 
)
static

Definition at line 92 of file hstore_io.c.

93 {
94  int st = GV_WAITVAL;
95 
96  state->wordlen = 32;
97  state->cur = state->word = palloc(state->wordlen);
98  *escaped = false;
99 
100  while (1)
101  {
102  if (st == GV_WAITVAL)
103  {
104  if (*(state->ptr) == '"')
105  {
106  *escaped = true;
107  st = GV_INESCVAL;
108  }
109  else if (*(state->ptr) == '\0')
110  {
111  return false;
112  }
113  else if (*(state->ptr) == '=' && !ignoreeq)
114  {
116  }
117  else if (*(state->ptr) == '\\')
118  {
119  st = GV_WAITESCIN;
120  }
121  else if (!isspace((unsigned char) *(state->ptr)))
122  {
123  *(state->cur) = *(state->ptr);
124  state->cur++;
125  st = GV_INVAL;
126  }
127  }
128  else if (st == GV_INVAL)
129  {
130  if (*(state->ptr) == '\\')
131  {
132  st = GV_WAITESCIN;
133  }
134  else if (*(state->ptr) == '=' && !ignoreeq)
135  {
136  state->ptr--;
137  return true;
138  }
139  else if (*(state->ptr) == ',' && ignoreeq)
140  {
141  state->ptr--;
142  return true;
143  }
144  else if (isspace((unsigned char) *(state->ptr)))
145  {
146  return true;
147  }
148  else if (*(state->ptr) == '\0')
149  {
150  state->ptr--;
151  return true;
152  }
153  else
154  {
155  RESIZEPRSBUF;
156  *(state->cur) = *(state->ptr);
157  state->cur++;
158  }
159  }
160  else if (st == GV_INESCVAL)
161  {
162  if (*(state->ptr) == '\\')
163  {
164  st = GV_WAITESCESCIN;
165  }
166  else if (*(state->ptr) == '"')
167  {
168  return true;
169  }
170  else if (*(state->ptr) == '\0')
171  {
172  PRSEOF;
173  }
174  else
175  {
176  RESIZEPRSBUF;
177  *(state->cur) = *(state->ptr);
178  state->cur++;
179  }
180  }
181  else if (st == GV_WAITESCIN)
182  {
183  if (*(state->ptr) == '\0')
184  PRSEOF;
185  RESIZEPRSBUF;
186  *(state->cur) = *(state->ptr);
187  state->cur++;
188  st = GV_INVAL;
189  }
190  else if (st == GV_WAITESCESCIN)
191  {
192  if (*(state->ptr) == '\0')
193  PRSEOF;
194  RESIZEPRSBUF;
195  *(state->cur) = *(state->ptr);
196  state->cur++;
197  st = GV_INESCVAL;
198  }
199  else
200  elog(ERROR, "unrecognized get_val state: %d", st);
201 
202  state->ptr++;
203  }
204 }
#define ERROR
Definition: elog.h:39
#define PRSSYNTAXERROR
Definition: hstore_io.c:58
#define GV_INVAL
Definition: hstore_io.c:86
#define GV_WAITESCESCIN
Definition: hstore_io.c:89
#define GV_INESCVAL
Definition: hstore_io.c:87
#define RESIZEPRSBUF
Definition: hstore_io.c:47
#define PRSEOF
Definition: hstore_io.c:72
#define GV_WAITVAL
Definition: hstore_io.c:85
#define GV_WAITESCIN
Definition: hstore_io.c:88
void * palloc(Size size)
Definition: mcxt.c:1226

References elog(), ERROR, GV_INESCVAL, GV_INVAL, GV_WAITESCESCIN, GV_WAITESCIN, GV_WAITVAL, palloc(), PRSEOF, PRSSYNTAXERROR, and RESIZEPRSBUF.

Referenced by parse_hstore().

◆ hstore_from_array()

Datum hstore_from_array ( PG_FUNCTION_ARGS  )

Definition at line 714 of file hstore_io.c.

715 {
716  ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
717  int ndims = ARR_NDIM(in_array);
718  int count;
719  int32 buflen;
720  HStore *out;
721  Pairs *pairs;
722  Datum *in_datums;
723  bool *in_nulls;
724  int in_count;
725  int i;
726 
727  Assert(ARR_ELEMTYPE(in_array) == TEXTOID);
728 
729  switch (ndims)
730  {
731  case 0:
732  out = hstorePairs(NULL, 0, 0);
733  PG_RETURN_POINTER(out);
734 
735  case 1:
736  if ((ARR_DIMS(in_array)[0]) % 2)
737  ereport(ERROR,
738  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
739  errmsg("array must have even number of elements")));
740  break;
741 
742  case 2:
743  if ((ARR_DIMS(in_array)[1]) != 2)
744  ereport(ERROR,
745  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
746  errmsg("array must have two columns")));
747  break;
748 
749  default:
750  ereport(ERROR,
751  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
752  errmsg("wrong number of array subscripts")));
753  }
754 
755  deconstruct_array_builtin(in_array, TEXTOID, &in_datums, &in_nulls, &in_count);
756 
757  count = in_count / 2;
758 
759  /* see discussion in hstoreArrayToPairs() */
760  if (count > MaxAllocSize / sizeof(Pairs))
761  ereport(ERROR,
762  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
763  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
764  count, (int) (MaxAllocSize / sizeof(Pairs)))));
765 
766  pairs = palloc(count * sizeof(Pairs));
767 
768  for (i = 0; i < count; ++i)
769  {
770  if (in_nulls[i * 2])
771  ereport(ERROR,
772  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
773  errmsg("null value not allowed for hstore key")));
774 
775  if (in_nulls[i * 2 + 1])
776  {
777  pairs[i].key = VARDATA(in_datums[i * 2]);
778  pairs[i].val = NULL;
779  pairs[i].keylen =
780  hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
781  pairs[i].vallen = 4;
782  pairs[i].isnull = true;
783  pairs[i].needfree = false;
784  }
785  else
786  {
787  pairs[i].key = VARDATA(in_datums[i * 2]);
788  pairs[i].val = VARDATA(in_datums[i * 2 + 1]);
789  pairs[i].keylen =
790  hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
791  pairs[i].vallen =
792  hstoreCheckValLen(VARSIZE(in_datums[i * 2 + 1]) - VARHDRSZ);
793  pairs[i].isnull = false;
794  pairs[i].needfree = false;
795  }
796  }
797 
798  count = hstoreUniquePairs(pairs, count, &buflen);
799 
800  out = hstorePairs(pairs, count, buflen);
801 
802  PG_RETURN_POINTER(out);
803 }
#define ARR_NDIM(a)
Definition: array.h:283
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define ARR_DIMS(a)
Definition: array.h:287
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3665
signed int int32
Definition: c.h:478
#define VARHDRSZ
Definition: c.h:676
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
HStore * hstorePairs(Pairs *pairs, int32 pcount, int32 buflen)
Definition: hstore_io.c:444
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:423
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:403
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:355
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
#define MaxAllocSize
Definition: memutils.h:40
uintptr_t Datum
Definition: postgres.h:64
Definition: hstore.h:45
char * val
Definition: hstore.h:164
bool isnull
Definition: hstore.h:167
size_t vallen
Definition: hstore.h:166
#define VARDATA(PTR)
Definition: varatt.h:278
#define VARSIZE(PTR)
Definition: varatt.h:279

References ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, Assert(), deconstruct_array_builtin(), ereport, errcode(), errmsg(), ERROR, hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), hstoreUniquePairs(), i, Pairs::isnull, Pairs::key, Pairs::keylen, MaxAllocSize, Pairs::needfree, palloc(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_POINTER, Pairs::val, Pairs::vallen, VARDATA, VARHDRSZ, and VARSIZE.

◆ hstore_from_arrays()

Datum hstore_from_arrays ( PG_FUNCTION_ARGS  )

Definition at line 598 of file hstore_io.c.

599 {
600  int32 buflen;
601  HStore *out;
602  Pairs *pairs;
603  Datum *key_datums;
604  bool *key_nulls;
605  int key_count;
606  Datum *value_datums;
607  bool *value_nulls;
608  int value_count;
609  ArrayType *key_array;
610  ArrayType *value_array;
611  int i;
612 
613  if (PG_ARGISNULL(0))
614  PG_RETURN_NULL();
615 
616  key_array = PG_GETARG_ARRAYTYPE_P(0);
617 
618  Assert(ARR_ELEMTYPE(key_array) == TEXTOID);
619 
620  /*
621  * must check >1 rather than != 1 because empty arrays have 0 dimensions,
622  * not 1
623  */
624 
625  if (ARR_NDIM(key_array) > 1)
626  ereport(ERROR,
627  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
628  errmsg("wrong number of array subscripts")));
629 
630  deconstruct_array_builtin(key_array, TEXTOID, &key_datums, &key_nulls, &key_count);
631 
632  /* see discussion in hstoreArrayToPairs() */
633  if (key_count > MaxAllocSize / sizeof(Pairs))
634  ereport(ERROR,
635  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
636  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
637  key_count, (int) (MaxAllocSize / sizeof(Pairs)))));
638 
639  /* value_array might be NULL */
640 
641  if (PG_ARGISNULL(1))
642  {
643  value_array = NULL;
644  value_count = key_count;
645  value_datums = NULL;
646  value_nulls = NULL;
647  }
648  else
649  {
650  value_array = PG_GETARG_ARRAYTYPE_P(1);
651 
652  Assert(ARR_ELEMTYPE(value_array) == TEXTOID);
653 
654  if (ARR_NDIM(value_array) > 1)
655  ereport(ERROR,
656  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
657  errmsg("wrong number of array subscripts")));
658 
659  if ((ARR_NDIM(key_array) > 0 || ARR_NDIM(value_array) > 0) &&
660  (ARR_NDIM(key_array) != ARR_NDIM(value_array) ||
661  ARR_DIMS(key_array)[0] != ARR_DIMS(value_array)[0] ||
662  ARR_LBOUND(key_array)[0] != ARR_LBOUND(value_array)[0]))
663  ereport(ERROR,
664  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
665  errmsg("arrays must have same bounds")));
666 
667  deconstruct_array_builtin(value_array, TEXTOID, &value_datums, &value_nulls, &value_count);
668 
669  Assert(key_count == value_count);
670  }
671 
672  pairs = palloc(key_count * sizeof(Pairs));
673 
674  for (i = 0; i < key_count; ++i)
675  {
676  if (key_nulls[i])
677  ereport(ERROR,
678  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
679  errmsg("null value not allowed for hstore key")));
680 
681  if (!value_nulls || value_nulls[i])
682  {
683  pairs[i].key = VARDATA(key_datums[i]);
684  pairs[i].val = NULL;
685  pairs[i].keylen =
686  hstoreCheckKeyLen(VARSIZE(key_datums[i]) - VARHDRSZ);
687  pairs[i].vallen = 4;
688  pairs[i].isnull = true;
689  pairs[i].needfree = false;
690  }
691  else
692  {
693  pairs[i].key = VARDATA(key_datums[i]);
694  pairs[i].val = VARDATA(value_datums[i]);
695  pairs[i].keylen =
696  hstoreCheckKeyLen(VARSIZE(key_datums[i]) - VARHDRSZ);
697  pairs[i].vallen =
698  hstoreCheckValLen(VARSIZE(value_datums[i]) - VARHDRSZ);
699  pairs[i].isnull = false;
700  pairs[i].needfree = false;
701  }
702  }
703 
704  key_count = hstoreUniquePairs(pairs, key_count, &buflen);
705 
706  out = hstorePairs(pairs, key_count, buflen);
707 
708  PG_RETURN_POINTER(out);
709 }
#define ARR_LBOUND(a)
Definition: array.h:289
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_NULL()
Definition: fmgr.h:345

References ARR_DIMS, ARR_ELEMTYPE, ARR_LBOUND, ARR_NDIM, Assert(), deconstruct_array_builtin(), ereport, errcode(), errmsg(), ERROR, hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), hstoreUniquePairs(), i, Pairs::isnull, Pairs::key, Pairs::keylen, MaxAllocSize, Pairs::needfree, palloc(), PG_ARGISNULL, PG_GETARG_ARRAYTYPE_P, PG_RETURN_NULL, PG_RETURN_POINTER, Pairs::val, Pairs::vallen, VARDATA, VARHDRSZ, and VARSIZE.

◆ hstore_from_record()

Datum hstore_from_record ( PG_FUNCTION_ARGS  )

Definition at line 830 of file hstore_io.c.

831 {
832  HeapTupleHeader rec;
833  int32 buflen;
834  HStore *out;
835  Pairs *pairs;
836  Oid tupType;
837  int32 tupTypmod;
838  TupleDesc tupdesc;
839  HeapTupleData tuple;
840  RecordIOData *my_extra;
841  int ncolumns;
842  int i,
843  j;
844  Datum *values;
845  bool *nulls;
846 
847  if (PG_ARGISNULL(0))
848  {
849  Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0);
850 
851  /*
852  * We have no tuple to look at, so the only source of type info is the
853  * argtype --- which might be domain over composite, but we don't care
854  * here, since we have no need to be concerned about domain
855  * constraints. The lookup_rowtype_tupdesc_domain call below will
856  * error out if we don't have a known composite type oid here.
857  */
858  tupType = argtype;
859  tupTypmod = -1;
860 
861  rec = NULL;
862  }
863  else
864  {
865  rec = PG_GETARG_HEAPTUPLEHEADER(0);
866 
867  /*
868  * Extract type info from the tuple itself -- this will work even for
869  * anonymous record types.
870  */
871  tupType = HeapTupleHeaderGetTypeId(rec);
872  tupTypmod = HeapTupleHeaderGetTypMod(rec);
873  }
874 
875  tupdesc = lookup_rowtype_tupdesc_domain(tupType, tupTypmod, false);
876  ncolumns = tupdesc->natts;
877 
878  /*
879  * We arrange to look up the needed I/O info just once per series of
880  * calls, assuming the record type doesn't change underneath us.
881  */
882  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
883  if (my_extra == NULL ||
884  my_extra->ncolumns != ncolumns)
885  {
886  fcinfo->flinfo->fn_extra =
887  MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
888  offsetof(RecordIOData, columns) +
889  ncolumns * sizeof(ColumnIOData));
890  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
891  my_extra->record_type = InvalidOid;
892  my_extra->record_typmod = 0;
893  }
894 
895  if (my_extra->record_type != tupType ||
896  my_extra->record_typmod != tupTypmod)
897  {
898  MemSet(my_extra, 0,
899  offsetof(RecordIOData, columns) +
900  ncolumns * sizeof(ColumnIOData));
901  my_extra->record_type = tupType;
902  my_extra->record_typmod = tupTypmod;
903  my_extra->ncolumns = ncolumns;
904  }
905 
906  Assert(ncolumns <= MaxTupleAttributeNumber); /* thus, no overflow */
907  pairs = palloc(ncolumns * sizeof(Pairs));
908 
909  if (rec)
910  {
911  /* Build a temporary HeapTuple control structure */
913  ItemPointerSetInvalid(&(tuple.t_self));
914  tuple.t_tableOid = InvalidOid;
915  tuple.t_data = rec;
916 
917  values = (Datum *) palloc(ncolumns * sizeof(Datum));
918  nulls = (bool *) palloc(ncolumns * sizeof(bool));
919 
920  /* Break down the tuple into fields */
921  heap_deform_tuple(&tuple, tupdesc, values, nulls);
922  }
923  else
924  {
925  values = NULL;
926  nulls = NULL;
927  }
928 
929  for (i = 0, j = 0; i < ncolumns; ++i)
930  {
931  ColumnIOData *column_info = &my_extra->columns[i];
932  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
933  Oid column_type = att->atttypid;
934  char *value;
935 
936  /* Ignore dropped columns in datatype */
937  if (att->attisdropped)
938  continue;
939 
940  pairs[j].key = NameStr(att->attname);
941  pairs[j].keylen = hstoreCheckKeyLen(strlen(NameStr(att->attname)));
942 
943  if (!nulls || nulls[i])
944  {
945  pairs[j].val = NULL;
946  pairs[j].vallen = 4;
947  pairs[j].isnull = true;
948  pairs[j].needfree = false;
949  ++j;
950  continue;
951  }
952 
953  /*
954  * Convert the column value to text
955  */
956  if (column_info->column_type != column_type)
957  {
958  bool typIsVarlena;
959 
960  getTypeOutputInfo(column_type,
961  &column_info->typiofunc,
962  &typIsVarlena);
963  fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
964  fcinfo->flinfo->fn_mcxt);
965  column_info->column_type = column_type;
966  }
967 
968  value = OutputFunctionCall(&column_info->proc, values[i]);
969 
970  pairs[j].val = value;
971  pairs[j].vallen = hstoreCheckValLen(strlen(value));
972  pairs[j].isnull = false;
973  pairs[j].needfree = false;
974  ++j;
975  }
976 
977  ncolumns = hstoreUniquePairs(pairs, j, &buflen);
978 
979  out = hstorePairs(pairs, ncolumns, buflen);
980 
981  ReleaseTupleDesc(tupdesc);
982 
983  PG_RETURN_POINTER(out);
984 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
#define NameStr(name)
Definition: c.h:730
#define MemSet(start, val, len)
Definition: c.h:1004
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:137
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1881
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1654
#define PG_GETARG_HEAPTUPLEHEADER(n)
Definition: fmgr.h:312
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
Definition: heaptuple.c:1249
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:466
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:456
#define MaxTupleAttributeNumber
Definition: htup_details.h:34
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:450
static struct @147 value
int j
Definition: isn.c:74
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
static void ItemPointerSetInvalid(ItemPointerData *pointer)
Definition: itemptr.h:184
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2865
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1021
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:209
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
FmgrInfo proc
Definition: hstore_io.c:815
Oid column_type
Definition: hstore_io.c:812
MemoryContext fn_mcxt
Definition: fmgr.h:65
ItemPointerData t_self
Definition: htup.h:65
uint32 t_len
Definition: htup.h:64
HeapTupleHeader t_data
Definition: htup.h:68
Oid t_tableOid
Definition: htup.h:66
ColumnIOData columns[FLEXIBLE_ARRAY_MEMBER]
Definition: hstore_io.c:825
Oid record_type
Definition: hstore_io.c:820
int32 record_typmod
Definition: hstore_io.c:821
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:122
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, bool noError)
Definition: typcache.c:1880

References Assert(), ColumnIOData::column_type, RecordIOData::columns, fmgr_info_cxt(), FmgrInfo::fn_mcxt, get_fn_expr_argtype(), getTypeOutputInfo(), heap_deform_tuple(), HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), hstoreUniquePairs(), i, if(), InvalidOid, Pairs::isnull, ItemPointerSetInvalid(), j, Pairs::key, Pairs::keylen, lookup_rowtype_tupdesc_domain(), MaxTupleAttributeNumber, MemoryContextAlloc(), MemSet, NameStr, TupleDescData::natts, RecordIOData::ncolumns, Pairs::needfree, OutputFunctionCall(), palloc(), PG_ARGISNULL, PG_GETARG_HEAPTUPLEHEADER, PG_RETURN_POINTER, ColumnIOData::proc, RecordIOData::record_type, RecordIOData::record_typmod, ReleaseTupleDesc, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, TupleDescAttr, ColumnIOData::typiofunc, Pairs::val, Pairs::vallen, value, and values.

◆ hstore_from_text()

Datum hstore_from_text ( PG_FUNCTION_ARGS  )

Definition at line 562 of file hstore_io.c.

563 {
564  text *key;
565  text *val = NULL;
566  Pairs p;
567  HStore *out;
568 
569  if (PG_ARGISNULL(0))
570  PG_RETURN_NULL();
571 
572  p.needfree = false;
573  key = PG_GETARG_TEXT_PP(0);
574  p.key = VARDATA_ANY(key);
576 
577  if (PG_ARGISNULL(1))
578  {
579  p.vallen = 0;
580  p.isnull = true;
581  }
582  else
583  {
584  val = PG_GETARG_TEXT_PP(1);
585  p.val = VARDATA_ANY(val);
587  p.isnull = false;
588  }
589 
590  out = hstorePairs(&p, 1, p.keylen + p.vallen);
591 
592  PG_RETURN_POINTER(out);
593 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
long val
Definition: informix.c:664
Definition: c.h:671
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

References hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), Pairs::isnull, Pairs::key, sort-test::key, Pairs::keylen, Pairs::needfree, PG_ARGISNULL, PG_GETARG_TEXT_PP, PG_RETURN_NULL, PG_RETURN_POINTER, Pairs::val, val, Pairs::vallen, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ hstore_in()

Datum hstore_in ( PG_FUNCTION_ARGS  )

Definition at line 475 of file hstore_io.c.

476 {
477  char *str = PG_GETARG_CSTRING(0);
478  Node *escontext = fcinfo->context;
479  HSParser state;
480  int32 buflen;
481  HStore *out;
482 
483  state.begin = str;
484  state.escontext = escontext;
485 
486  if (!parse_hstore(&state))
487  PG_RETURN_NULL();
488 
489  state.pcur = hstoreUniquePairs(state.pairs, state.pcur, &buflen);
490 
491  out = hstorePairs(state.pairs, state.pcur, buflen);
492 
493  PG_RETURN_POINTER(out);
494 }
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
static bool parse_hstore(HSParser *state)
Definition: hstore_io.c:214
Definition: nodes.h:129

References hstorePairs(), hstoreUniquePairs(), parse_hstore(), PG_GETARG_CSTRING, PG_RETURN_NULL, PG_RETURN_POINTER, and generate_unaccent_rules::str.

◆ hstore_out()

Datum hstore_out ( PG_FUNCTION_ARGS  )

Definition at line 1221 of file hstore_io.c.

1222 {
1223  HStore *in = PG_GETARG_HSTORE_P(0);
1224  int buflen,
1225  i;
1226  int count = HS_COUNT(in);
1227  char *out,
1228  *ptr;
1229  char *base = STRPTR(in);
1230  HEntry *entries = ARRPTR(in);
1231 
1232  if (count == 0)
1234 
1235  buflen = 0;
1236 
1237  /*
1238  * this loop overestimates due to pessimistic assumptions about escaping,
1239  * so very large hstore values can't be output. this could be fixed, but
1240  * many other data types probably have the same issue. This replaced code
1241  * that used the original varlena size for calculations, which was wrong
1242  * in some subtle ways.
1243  */
1244 
1245  for (i = 0; i < count; i++)
1246  {
1247  /* include "" and => and comma-space */
1248  buflen += 6 + 2 * HSTORE_KEYLEN(entries, i);
1249  /* include "" only if nonnull */
1250  buflen += 2 + (HSTORE_VALISNULL(entries, i)
1251  ? 2
1252  : 2 * HSTORE_VALLEN(entries, i));
1253  }
1254 
1255  out = ptr = palloc(buflen);
1256 
1257  for (i = 0; i < count; i++)
1258  {
1259  *ptr++ = '"';
1260  ptr = cpw(ptr, HSTORE_KEY(entries, base, i), HSTORE_KEYLEN(entries, i));
1261  *ptr++ = '"';
1262  *ptr++ = '=';
1263  *ptr++ = '>';
1264  if (HSTORE_VALISNULL(entries, i))
1265  {
1266  *ptr++ = 'N';
1267  *ptr++ = 'U';
1268  *ptr++ = 'L';
1269  *ptr++ = 'L';
1270  }
1271  else
1272  {
1273  *ptr++ = '"';
1274  ptr = cpw(ptr, HSTORE_VAL(entries, base, i), HSTORE_VALLEN(entries, i));
1275  *ptr++ = '"';
1276  }
1277 
1278  if (i + 1 != count)
1279  {
1280  *ptr++ = ',';
1281  *ptr++ = ' ';
1282  }
1283  }
1284  *ptr = '\0';
1285 
1286  PG_RETURN_CSTRING(out);
1287 }
#define ARRPTR(x)
Definition: cube.c:25
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define HS_COUNT(hsp_)
Definition: hstore.h:61
#define HSTORE_KEY(arr_, str_, i_)
Definition: hstore.h:79
#define PG_GETARG_HSTORE_P(x)
Definition: hstore.h:154
#define HSTORE_VALISNULL(arr_, i_)
Definition: hstore.h:83
#define HSTORE_VALLEN(arr_, i_)
Definition: hstore.h:82
#define HSTORE_KEYLEN(arr_, i_)
Definition: hstore.h:81
#define HSTORE_VAL(arr_, str_, i_)
Definition: hstore.h:80
#define STRPTR(x)
Definition: hstore.h:76
static char * cpw(char *dst, char *src, int len)
Definition: hstore_io.c:1206
char * pstrdup(const char *in)
Definition: mcxt.c:1644
Definition: hstore.h:19

References ARRPTR, cpw(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, palloc(), PG_GETARG_HSTORE_P, PG_RETURN_CSTRING, pstrdup(), and STRPTR.

◆ HSTORE_POLLUTE()

HSTORE_POLLUTE ( hstore_from_text  ,
tconvert   
)

◆ hstore_populate_record()

Datum hstore_populate_record ( PG_FUNCTION_ARGS  )

Definition at line 989 of file hstore_io.c.

990 {
991  Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, 0);
992  HStore *hs;
993  HEntry *entries;
994  char *ptr;
995  HeapTupleHeader rec;
996  Oid tupType;
997  int32 tupTypmod;
998  TupleDesc tupdesc;
999  HeapTupleData tuple;
1000  HeapTuple rettuple;
1001  RecordIOData *my_extra;
1002  int ncolumns;
1003  int i;
1004  Datum *values;
1005  bool *nulls;
1006 
1007  if (!type_is_rowtype(argtype))
1008  ereport(ERROR,
1009  (errcode(ERRCODE_DATATYPE_MISMATCH),
1010  errmsg("first argument must be a rowtype")));
1011 
1012  if (PG_ARGISNULL(0))
1013  {
1014  if (PG_ARGISNULL(1))
1015  PG_RETURN_NULL();
1016 
1017  rec = NULL;
1018 
1019  /*
1020  * We have no tuple to look at, so the only source of type info is the
1021  * argtype. The lookup_rowtype_tupdesc_domain call below will error
1022  * out if we don't have a known composite type oid here.
1023  */
1024  tupType = argtype;
1025  tupTypmod = -1;
1026  }
1027  else
1028  {
1029  rec = PG_GETARG_HEAPTUPLEHEADER(0);
1030 
1031  if (PG_ARGISNULL(1))
1032  PG_RETURN_POINTER(rec);
1033 
1034  /*
1035  * Extract type info from the tuple itself -- this will work even for
1036  * anonymous record types.
1037  */
1038  tupType = HeapTupleHeaderGetTypeId(rec);
1039  tupTypmod = HeapTupleHeaderGetTypMod(rec);
1040  }
1041 
1042  hs = PG_GETARG_HSTORE_P(1);
1043  entries = ARRPTR(hs);
1044  ptr = STRPTR(hs);
1045 
1046  /*
1047  * if the input hstore is empty, we can only skip the rest if we were
1048  * passed in a non-null record, since otherwise there may be issues with
1049  * domain nulls.
1050  */
1051 
1052  if (HS_COUNT(hs) == 0 && rec)
1053  PG_RETURN_POINTER(rec);
1054 
1055  /*
1056  * Lookup the input record's tupdesc. For the moment, we don't worry
1057  * about whether it is a domain over composite.
1058  */
1059  tupdesc = lookup_rowtype_tupdesc_domain(tupType, tupTypmod, false);
1060  ncolumns = tupdesc->natts;
1061 
1062  if (rec)
1063  {
1064  /* Build a temporary HeapTuple control structure */
1065  tuple.t_len = HeapTupleHeaderGetDatumLength(rec);
1066  ItemPointerSetInvalid(&(tuple.t_self));
1067  tuple.t_tableOid = InvalidOid;
1068  tuple.t_data = rec;
1069  }
1070 
1071  /*
1072  * We arrange to look up the needed I/O info just once per series of
1073  * calls, assuming the record type doesn't change underneath us.
1074  */
1075  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
1076  if (my_extra == NULL ||
1077  my_extra->ncolumns != ncolumns)
1078  {
1079  fcinfo->flinfo->fn_extra =
1080  MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
1081  offsetof(RecordIOData, columns) +
1082  ncolumns * sizeof(ColumnIOData));
1083  my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
1084  my_extra->record_type = InvalidOid;
1085  my_extra->record_typmod = 0;
1086  my_extra->domain_info = NULL;
1087  }
1088 
1089  if (my_extra->record_type != tupType ||
1090  my_extra->record_typmod != tupTypmod)
1091  {
1092  MemSet(my_extra, 0,
1093  offsetof(RecordIOData, columns) +
1094  ncolumns * sizeof(ColumnIOData));
1095  my_extra->record_type = tupType;
1096  my_extra->record_typmod = tupTypmod;
1097  my_extra->ncolumns = ncolumns;
1098  }
1099 
1100  values = (Datum *) palloc(ncolumns * sizeof(Datum));
1101  nulls = (bool *) palloc(ncolumns * sizeof(bool));
1102 
1103  if (rec)
1104  {
1105  /* Break down the tuple into fields */
1106  heap_deform_tuple(&tuple, tupdesc, values, nulls);
1107  }
1108  else
1109  {
1110  for (i = 0; i < ncolumns; ++i)
1111  {
1112  values[i] = (Datum) 0;
1113  nulls[i] = true;
1114  }
1115  }
1116 
1117  for (i = 0; i < ncolumns; ++i)
1118  {
1119  ColumnIOData *column_info = &my_extra->columns[i];
1120  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1121  Oid column_type = att->atttypid;
1122  char *value;
1123  int idx;
1124  int vallen;
1125 
1126  /* Ignore dropped columns in datatype */
1127  if (att->attisdropped)
1128  {
1129  nulls[i] = true;
1130  continue;
1131  }
1132 
1133  idx = hstoreFindKey(hs, 0,
1134  NameStr(att->attname),
1135  strlen(NameStr(att->attname)));
1136 
1137  /*
1138  * we can't just skip here if the key wasn't found since we might have
1139  * a domain to deal with. If we were passed in a non-null record
1140  * datum, we assume that the existing values are valid (if they're
1141  * not, then it's not our fault), but if we were passed in a null,
1142  * then every field which we don't populate needs to be run through
1143  * the input function just in case it's a domain type.
1144  */
1145  if (idx < 0 && rec)
1146  continue;
1147 
1148  /*
1149  * Prepare to convert the column value from text
1150  */
1151  if (column_info->column_type != column_type)
1152  {
1153  getTypeInputInfo(column_type,
1154  &column_info->typiofunc,
1155  &column_info->typioparam);
1156  fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
1157  fcinfo->flinfo->fn_mcxt);
1158  column_info->column_type = column_type;
1159  }
1160 
1161  if (idx < 0 || HSTORE_VALISNULL(entries, idx))
1162  {
1163  /*
1164  * need InputFunctionCall to happen even for nulls, so that domain
1165  * checks are done
1166  */
1167  values[i] = InputFunctionCall(&column_info->proc, NULL,
1168  column_info->typioparam,
1169  att->atttypmod);
1170  nulls[i] = true;
1171  }
1172  else
1173  {
1174  vallen = HSTORE_VALLEN(entries, idx);
1175  value = palloc(1 + vallen);
1176  memcpy(value, HSTORE_VAL(entries, ptr, idx), vallen);
1177  value[vallen] = 0;
1178 
1179  values[i] = InputFunctionCall(&column_info->proc, value,
1180  column_info->typioparam,
1181  att->atttypmod);
1182  nulls[i] = false;
1183  }
1184  }
1185 
1186  rettuple = heap_form_tuple(tupdesc, values, nulls);
1187 
1188  /*
1189  * If the target type is domain over composite, all we know at this point
1190  * is that we've made a valid value of the base composite type. Must
1191  * check domain constraints before deciding we're done.
1192  */
1193  if (argtype != tupdesc->tdtypeid)
1194  domain_check(HeapTupleGetDatum(rettuple), false,
1195  argtype,
1196  &my_extra->domain_info,
1197  fcinfo->flinfo->fn_mcxt);
1198 
1199  ReleaseTupleDesc(tupdesc);
1200 
1202 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
void domain_check(Datum value, bool isnull, Oid domainType, void **extra, MemoryContext mcxt)
Definition: domains.c:343
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1501
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
PGDLLEXPORT int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen)
Definition: hstore_op.c:36
bool type_is_rowtype(Oid typid)
Definition: lsyscache.c:2613
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2832
Oid typioparam
Definition: hstore_io.c:814
void * domain_info
Definition: hstore_io.c:823
Oid tdtypeid
Definition: tupdesc.h:82

References ARRPTR, ColumnIOData::column_type, RecordIOData::columns, domain_check(), RecordIOData::domain_info, ereport, errcode(), errmsg(), ERROR, fmgr_info_cxt(), FmgrInfo::fn_mcxt, get_fn_expr_argtype(), getTypeInputInfo(), heap_deform_tuple(), heap_form_tuple(), HeapTupleGetDatum(), HeapTupleHeaderGetDatumLength, HeapTupleHeaderGetTypeId, HeapTupleHeaderGetTypMod, HS_COUNT, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, hstoreFindKey(), i, idx(), if(), InputFunctionCall(), InvalidOid, ItemPointerSetInvalid(), lookup_rowtype_tupdesc_domain(), MemoryContextAlloc(), MemSet, NameStr, TupleDescData::natts, RecordIOData::ncolumns, palloc(), PG_ARGISNULL, PG_GETARG_HEAPTUPLEHEADER, PG_GETARG_HSTORE_P, PG_RETURN_DATUM, PG_RETURN_NULL, PG_RETURN_POINTER, ColumnIOData::proc, RecordIOData::record_type, RecordIOData::record_typmod, ReleaseTupleDesc, STRPTR, HeapTupleData::t_data, HeapTupleData::t_len, HeapTupleData::t_self, HeapTupleData::t_tableOid, TupleDescData::tdtypeid, TupleDescAttr, type_is_rowtype(), ColumnIOData::typiofunc, ColumnIOData::typioparam, value, and values.

◆ hstore_recv()

Datum hstore_recv ( PG_FUNCTION_ARGS  )

Definition at line 499 of file hstore_io.c.

500 {
501  int32 buflen;
502  HStore *out;
503  Pairs *pairs;
504  int32 i;
505  int32 pcount;
507 
508  pcount = pq_getmsgint(buf, 4);
509 
510  if (pcount == 0)
511  {
512  out = hstorePairs(NULL, 0, 0);
513  PG_RETURN_POINTER(out);
514  }
515 
516  if (pcount < 0 || pcount > MaxAllocSize / sizeof(Pairs))
517  ereport(ERROR,
518  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
519  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
520  pcount, (int) (MaxAllocSize / sizeof(Pairs)))));
521  pairs = palloc(pcount * sizeof(Pairs));
522 
523  for (i = 0; i < pcount; ++i)
524  {
525  int rawlen = pq_getmsgint(buf, 4);
526  int len;
527 
528  if (rawlen < 0)
529  ereport(ERROR,
530  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
531  errmsg("null value not allowed for hstore key")));
532 
533  pairs[i].key = pq_getmsgtext(buf, rawlen, &len);
534  pairs[i].keylen = hstoreCheckKeyLen(len);
535  pairs[i].needfree = true;
536 
537  rawlen = pq_getmsgint(buf, 4);
538  if (rawlen < 0)
539  {
540  pairs[i].val = NULL;
541  pairs[i].vallen = 0;
542  pairs[i].isnull = true;
543  }
544  else
545  {
546  pairs[i].val = pq_getmsgtext(buf, rawlen, &len);
547  pairs[i].vallen = hstoreCheckValLen(len);
548  pairs[i].isnull = false;
549  }
550  }
551 
552  pcount = hstoreUniquePairs(pairs, pcount, &buflen);
553 
554  out = hstorePairs(pairs, pcount, buflen);
555 
556  PG_RETURN_POINTER(out);
557 }
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
static char * buf
Definition: pg_test_fsync.c:67
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:418
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:549
StringInfoData * StringInfo
Definition: stringinfo.h:44

References buf, ereport, errcode(), errmsg(), ERROR, hstoreCheckKeyLen(), hstoreCheckValLen(), hstorePairs(), hstoreUniquePairs(), i, Pairs::isnull, Pairs::key, Pairs::keylen, len, MaxAllocSize, Pairs::needfree, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, pq_getmsgint(), pq_getmsgtext(), Pairs::val, and Pairs::vallen.

◆ hstore_send()

Datum hstore_send ( PG_FUNCTION_ARGS  )

Definition at line 1292 of file hstore_io.c.

1293 {
1294  HStore *in = PG_GETARG_HSTORE_P(0);
1295  int i;
1296  int count = HS_COUNT(in);
1297  char *base = STRPTR(in);
1298  HEntry *entries = ARRPTR(in);
1300 
1301  pq_begintypsend(&buf);
1302 
1303  pq_sendint32(&buf, count);
1304 
1305  for (i = 0; i < count; i++)
1306  {
1307  int32 keylen = HSTORE_KEYLEN(entries, i);
1308 
1309  pq_sendint32(&buf, keylen);
1310  pq_sendtext(&buf, HSTORE_KEY(entries, base, i), keylen);
1311  if (HSTORE_VALISNULL(entries, i))
1312  {
1313  pq_sendint32(&buf, -1);
1314  }
1315  else
1316  {
1317  int32 vallen = HSTORE_VALLEN(entries, i);
1318 
1319  pq_sendint32(&buf, vallen);
1320  pq_sendtext(&buf, HSTORE_VAL(entries, base, i), vallen);
1321  }
1322  }
1323 
1325 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:175
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:329
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:349
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145

References ARRPTR, buf, HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, PG_GETARG_HSTORE_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint32(), pq_sendtext(), and STRPTR.

◆ hstore_to_json()

Datum hstore_to_json ( PG_FUNCTION_ARGS  )

Definition at line 1393 of file hstore_io.c.

1394 {
1395  HStore *in = PG_GETARG_HSTORE_P(0);
1396  int i;
1397  int count = HS_COUNT(in);
1398  char *base = STRPTR(in);
1399  HEntry *entries = ARRPTR(in);
1400  StringInfoData tmp,
1401  dst;
1402 
1403  if (count == 0)
1405 
1406  initStringInfo(&tmp);
1407  initStringInfo(&dst);
1408 
1409  appendStringInfoChar(&dst, '{');
1410 
1411  for (i = 0; i < count; i++)
1412  {
1413  resetStringInfo(&tmp);
1414  appendBinaryStringInfo(&tmp, HSTORE_KEY(entries, base, i),
1415  HSTORE_KEYLEN(entries, i));
1416  escape_json(&dst, tmp.data);
1417  appendStringInfoString(&dst, ": ");
1418  if (HSTORE_VALISNULL(entries, i))
1419  appendStringInfoString(&dst, "null");
1420  else
1421  {
1422  resetStringInfo(&tmp);
1423  appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1424  HSTORE_VALLEN(entries, i));
1425  escape_json(&dst, tmp.data);
1426  }
1427 
1428  if (i + 1 != count)
1429  appendStringInfoString(&dst, ", ");
1430  }
1431  appendStringInfoChar(&dst, '}');
1432 
1434 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
void escape_json(StringInfo buf, const char *str)
Definition: json.c:1627
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:75
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:227
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:194

References appendBinaryStringInfo(), appendStringInfoChar(), appendStringInfoString(), ARRPTR, cstring_to_text_with_len(), StringInfoData::data, escape_json(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, initStringInfo(), StringInfoData::len, PG_GETARG_HSTORE_P, PG_RETURN_TEXT_P, resetStringInfo(), and STRPTR.

◆ hstore_to_json_loose()

Datum hstore_to_json_loose ( PG_FUNCTION_ARGS  )

Definition at line 1338 of file hstore_io.c.

1339 {
1340  HStore *in = PG_GETARG_HSTORE_P(0);
1341  int i;
1342  int count = HS_COUNT(in);
1343  char *base = STRPTR(in);
1344  HEntry *entries = ARRPTR(in);
1345  StringInfoData tmp,
1346  dst;
1347 
1348  if (count == 0)
1350 
1351  initStringInfo(&tmp);
1352  initStringInfo(&dst);
1353 
1354  appendStringInfoChar(&dst, '{');
1355 
1356  for (i = 0; i < count; i++)
1357  {
1358  resetStringInfo(&tmp);
1359  appendBinaryStringInfo(&tmp, HSTORE_KEY(entries, base, i),
1360  HSTORE_KEYLEN(entries, i));
1361  escape_json(&dst, tmp.data);
1362  appendStringInfoString(&dst, ": ");
1363  if (HSTORE_VALISNULL(entries, i))
1364  appendStringInfoString(&dst, "null");
1365  /* guess that values of 't' or 'f' are booleans */
1366  else if (HSTORE_VALLEN(entries, i) == 1 &&
1367  *(HSTORE_VAL(entries, base, i)) == 't')
1368  appendStringInfoString(&dst, "true");
1369  else if (HSTORE_VALLEN(entries, i) == 1 &&
1370  *(HSTORE_VAL(entries, base, i)) == 'f')
1371  appendStringInfoString(&dst, "false");
1372  else
1373  {
1374  resetStringInfo(&tmp);
1375  appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1376  HSTORE_VALLEN(entries, i));
1377  if (IsValidJsonNumber(tmp.data, tmp.len))
1378  appendBinaryStringInfo(&dst, tmp.data, tmp.len);
1379  else
1380  escape_json(&dst, tmp.data);
1381  }
1382 
1383  if (i + 1 != count)
1384  appendStringInfoString(&dst, ", ");
1385  }
1386  appendStringInfoChar(&dst, '}');
1387 
1389 }
bool IsValidJsonNumber(const char *str, int len)
Definition: jsonapi.c:105

References appendBinaryStringInfo(), appendStringInfoChar(), appendStringInfoString(), ARRPTR, cstring_to_text_with_len(), StringInfoData::data, escape_json(), HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, initStringInfo(), IsValidJsonNumber(), StringInfoData::len, PG_GETARG_HSTORE_P, PG_RETURN_TEXT_P, resetStringInfo(), and STRPTR.

◆ hstore_to_jsonb()

Datum hstore_to_jsonb ( PG_FUNCTION_ARGS  )

Definition at line 1438 of file hstore_io.c.

1439 {
1440  HStore *in = PG_GETARG_HSTORE_P(0);
1441  int i;
1442  int count = HS_COUNT(in);
1443  char *base = STRPTR(in);
1444  HEntry *entries = ARRPTR(in);
1445  JsonbParseState *state = NULL;
1446  JsonbValue *res;
1447 
1448  (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1449 
1450  for (i = 0; i < count; i++)
1451  {
1452  JsonbValue key,
1453  val;
1454 
1455  key.type = jbvString;
1456  key.val.string.len = HSTORE_KEYLEN(entries, i);
1457  key.val.string.val = HSTORE_KEY(entries, base, i);
1458 
1459  (void) pushJsonbValue(&state, WJB_KEY, &key);
1460 
1461  if (HSTORE_VALISNULL(entries, i))
1462  {
1463  val.type = jbvNull;
1464  }
1465  else
1466  {
1467  val.type = jbvString;
1468  val.val.string.len = HSTORE_VALLEN(entries, i);
1469  val.val.string.val = HSTORE_VAL(entries, base, i);
1470  }
1471  (void) pushJsonbValue(&state, WJB_VALUE, &val);
1472  }
1473 
1475 
1477 }
@ jbvNull
Definition: jsonb.h:228
@ jbvString
Definition: jsonb.h:229
@ WJB_KEY
Definition: jsonb.h:23
@ WJB_VALUE
Definition: jsonb.h:24
@ WJB_END_OBJECT
Definition: jsonb.h:29
@ WJB_BEGIN_OBJECT
Definition: jsonb.h:28
Jsonb * JsonbValueToJsonb(JsonbValue *val)
Definition: jsonb_util.c:94
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:568

References ARRPTR, HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, jbvNull, jbvString, JsonbValueToJsonb(), sort-test::key, PG_GETARG_HSTORE_P, PG_RETURN_POINTER, pushJsonbValue(), res, STRPTR, val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

◆ hstore_to_jsonb_loose()

Datum hstore_to_jsonb_loose ( PG_FUNCTION_ARGS  )

Definition at line 1481 of file hstore_io.c.

1482 {
1483  HStore *in = PG_GETARG_HSTORE_P(0);
1484  int i;
1485  int count = HS_COUNT(in);
1486  char *base = STRPTR(in);
1487  HEntry *entries = ARRPTR(in);
1488  JsonbParseState *state = NULL;
1489  JsonbValue *res;
1490  StringInfoData tmp;
1491 
1492  initStringInfo(&tmp);
1493 
1494  (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1495 
1496  for (i = 0; i < count; i++)
1497  {
1498  JsonbValue key,
1499  val;
1500 
1501  key.type = jbvString;
1502  key.val.string.len = HSTORE_KEYLEN(entries, i);
1503  key.val.string.val = HSTORE_KEY(entries, base, i);
1504 
1505  (void) pushJsonbValue(&state, WJB_KEY, &key);
1506 
1507  if (HSTORE_VALISNULL(entries, i))
1508  {
1509  val.type = jbvNull;
1510  }
1511  /* guess that values of 't' or 'f' are booleans */
1512  else if (HSTORE_VALLEN(entries, i) == 1 &&
1513  *(HSTORE_VAL(entries, base, i)) == 't')
1514  {
1515  val.type = jbvBool;
1516  val.val.boolean = true;
1517  }
1518  else if (HSTORE_VALLEN(entries, i) == 1 &&
1519  *(HSTORE_VAL(entries, base, i)) == 'f')
1520  {
1521  val.type = jbvBool;
1522  val.val.boolean = false;
1523  }
1524  else
1525  {
1526  resetStringInfo(&tmp);
1527  appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1528  HSTORE_VALLEN(entries, i));
1529  if (IsValidJsonNumber(tmp.data, tmp.len))
1530  {
1531  Datum numd;
1532 
1533  val.type = jbvNumeric;
1535  CStringGetDatum(tmp.data),
1537  Int32GetDatum(-1));
1538  val.val.numeric = DatumGetNumeric(numd);
1539  }
1540  else
1541  {
1542  val.type = jbvString;
1543  val.val.string.len = HSTORE_VALLEN(entries, i);
1544  val.val.string.val = HSTORE_VAL(entries, base, i);
1545  }
1546  }
1547  (void) pushJsonbValue(&state, WJB_VALUE, &val);
1548  }
1549 
1551 
1553 }
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:627
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:646
@ jbvNumeric
Definition: jsonb.h:230
@ jbvBool
Definition: jsonb.h:231
static Numeric DatumGetNumeric(Datum X)
Definition: numeric.h:60
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212

References appendBinaryStringInfo(), ARRPTR, CStringGetDatum(), StringInfoData::data, DatumGetNumeric(), DirectFunctionCall3, HS_COUNT, HSTORE_KEY, HSTORE_KEYLEN, HSTORE_VAL, HSTORE_VALISNULL, HSTORE_VALLEN, i, initStringInfo(), Int32GetDatum(), InvalidOid, IsValidJsonNumber(), jbvBool, jbvNull, jbvNumeric, jbvString, JsonbValueToJsonb(), sort-test::key, StringInfoData::len, numeric_in(), ObjectIdGetDatum(), PG_GETARG_HSTORE_P, PG_RETURN_POINTER, pushJsonbValue(), res, resetStringInfo(), STRPTR, val, WJB_BEGIN_OBJECT, WJB_END_OBJECT, WJB_KEY, and WJB_VALUE.

◆ hstoreCheckKeyLen()

size_t hstoreCheckKeyLen ( size_t  len)

Definition at line 403 of file hstore_io.c.

404 {
405  if (len > HSTORE_MAX_KEY_LEN)
406  ereport(ERROR,
407  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
408  errmsg("string too long for hstore key")));
409  return len;
410 }
#define HSTORE_MAX_KEY_LEN
Definition: hstore.h:41

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

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

◆ hstoreCheckKeyLength()

static bool hstoreCheckKeyLength ( size_t  len,
HSParser state 
)
static

Definition at line 413 of file hstore_io.c.

414 {
415  if (len > HSTORE_MAX_KEY_LEN)
416  ereturn(state->escontext, false,
417  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
418  errmsg("string too long for hstore key")));
419  return true;
420 }
#define ereturn(context, dummy_value,...)
Definition: elog.h:276

References ereturn, errcode(), errmsg(), HSTORE_MAX_KEY_LEN, and len.

Referenced by parse_hstore().

◆ hstoreCheckValLen()

size_t hstoreCheckValLen ( size_t  len)

Definition at line 423 of file hstore_io.c.

424 {
426  ereport(ERROR,
427  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
428  errmsg("string too long for hstore value")));
429  return len;
430 }
#define HSTORE_MAX_VALUE_LEN
Definition: hstore.h:42

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

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

◆ hstoreCheckValLength()

static bool hstoreCheckValLength ( size_t  len,
HSParser state 
)
static

Definition at line 433 of file hstore_io.c.

434 {
436  ereturn(state->escontext, false,
437  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
438  errmsg("string too long for hstore value")));
439  return true;
440 }

References ereturn, errcode(), errmsg(), HSTORE_MAX_VALUE_LEN, and len.

Referenced by parse_hstore().

◆ hstorePairs()

HStore* hstorePairs ( Pairs pairs,
int32  pcount,
int32  buflen 
)

Definition at line 444 of file hstore_io.c.

445 {
446  HStore *out;
447  HEntry *entry;
448  char *ptr;
449  char *buf;
450  int32 len;
451  int32 i;
452 
453  len = CALCDATASIZE(pcount, buflen);
454  out = palloc(len);
455  SET_VARSIZE(out, len);
456  HS_SETCOUNT(out, pcount);
457 
458  if (pcount == 0)
459  return out;
460 
461  entry = ARRPTR(out);
462  buf = ptr = STRPTR(out);
463 
464  for (i = 0; i < pcount; i++)
465  HS_ADDITEM(entry, buf, ptr, pairs[i]);
466 
467  HS_FINALIZE(out, pcount, buf, ptr);
468 
469  return out;
470 }
#define CALCDATASIZE(x, lenstr)
Definition: hstore.h:72
#define HS_FINALIZE(hsp_, count_, buf_, ptr_)
Definition: hstore.h:129
#define HS_ADDITEM(dent_, dbuf_, dptr_, pair_)
Definition: hstore.h:112
#define HS_SETCOUNT(hsp_, c_)
Definition: hstore.h:62
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

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

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

◆ hstoreUniquePairs()

int hstoreUniquePairs ( Pairs a,
int32  l,
int32 buflen 
)

Definition at line 355 of file hstore_io.c.

356 {
357  Pairs *ptr,
358  *res;
359 
360  *buflen = 0;
361  if (l < 2)
362  {
363  if (l == 1)
364  *buflen = a->keylen + ((a->isnull) ? 0 : a->vallen);
365  return l;
366  }
367 
368  qsort(a, l, sizeof(Pairs), comparePairs);
369 
370  /*
371  * We can't use qunique here because we have some clean-up code to run on
372  * removed elements.
373  */
374  ptr = a + 1;
375  res = a;
376  while (ptr - a < l)
377  {
378  if (ptr->keylen == res->keylen &&
379  memcmp(ptr->key, res->key, res->keylen) == 0)
380  {
381  if (ptr->needfree)
382  {
383  pfree(ptr->key);
384  pfree(ptr->val);
385  }
386  }
387  else
388  {
389  *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
390  res++;
391  if (res != ptr)
392  memcpy(res, ptr, sizeof(Pairs));
393  }
394 
395  ptr++;
396  }
397 
398  *buflen += res->keylen + ((res->isnull) ? 0 : res->vallen);
399  return res + 1 - a;
400 }
static int comparePairs(const void *a, const void *b)
Definition: hstore_io.c:325
void pfree(void *pointer)
Definition: mcxt.c:1456
#define qsort(a, b, c, d)
Definition: port.h:445

References a, comparePairs(), Pairs::key, Pairs::keylen, Pairs::needfree, pfree(), qsort, res, and Pairs::val.

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

◆ parse_hstore()

static bool parse_hstore ( HSParser state)
static

Definition at line 214 of file hstore_io.c.

215 {
216  int st = WKEY;
217  bool escaped = false;
218 
219  state->plen = 16;
220  state->pairs = (Pairs *) palloc(sizeof(Pairs) * state->plen);
221  state->pcur = 0;
222  state->ptr = state->begin;
223  state->word = NULL;
224 
225  while (1)
226  {
227  if (st == WKEY)
228  {
229  if (!get_val(state, false, &escaped))
230  {
231  if (SOFT_ERROR_OCCURRED(state->escontext))
232  return false;
233  return true; /* EOF, all okay */
234  }
235  if (state->pcur >= state->plen)
236  {
237  state->plen *= 2;
238  state->pairs = (Pairs *) repalloc(state->pairs, sizeof(Pairs) * state->plen);
239  }
240  if (!hstoreCheckKeyLength(state->cur - state->word, state))
241  return false;
242  state->pairs[state->pcur].key = state->word;
243  state->pairs[state->pcur].keylen = state->cur - state->word;
244  state->pairs[state->pcur].val = NULL;
245  state->word = NULL;
246  st = WEQ;
247  }
248  else if (st == WEQ)
249  {
250  if (*(state->ptr) == '=')
251  {
252  st = WGT;
253  }
254  else if (*(state->ptr) == '\0')
255  {
256  PRSEOF;
257  }
258  else if (!isspace((unsigned char) *(state->ptr)))
259  {
261  }
262  }
263  else if (st == WGT)
264  {
265  if (*(state->ptr) == '>')
266  {
267  st = WVAL;
268  }
269  else if (*(state->ptr) == '\0')
270  {
271  PRSEOF;
272  }
273  else
274  {
276  }
277  }
278  else if (st == WVAL)
279  {
280  if (!get_val(state, true, &escaped))
281  {
282  if (SOFT_ERROR_OCCURRED(state->escontext))
283  return false;
284  PRSEOF;
285  }
286  if (!hstoreCheckValLength(state->cur - state->word, state))
287  return false;
288  state->pairs[state->pcur].val = state->word;
289  state->pairs[state->pcur].vallen = state->cur - state->word;
290  state->pairs[state->pcur].isnull = false;
291  state->pairs[state->pcur].needfree = true;
292  if (state->cur - state->word == 4 && !escaped)
293  {
294  state->word[4] = '\0';
295  if (pg_strcasecmp(state->word, "null") == 0)
296  state->pairs[state->pcur].isnull = true;
297  }
298  state->word = NULL;
299  state->pcur++;
300  st = WDEL;
301  }
302  else if (st == WDEL)
303  {
304  if (*(state->ptr) == ',')
305  {
306  st = WKEY;
307  }
308  else if (*(state->ptr) == '\0')
309  {
310  return true;
311  }
312  else if (!isspace((unsigned char) *(state->ptr)))
313  {
315  }
316  }
317  else
318  elog(ERROR, "unrecognized parse_hstore state: %d", st);
319 
320  state->ptr++;
321  }
322 }
#define WDEL
Definition: hstore_io.c:210
static bool get_val(HSParser *state, bool ignoreeq, bool *escaped)
Definition: hstore_io.c:92
#define WKEY
Definition: hstore_io.c:206
static bool hstoreCheckValLength(size_t len, HSParser *state)
Definition: hstore_io.c:433
#define WGT
Definition: hstore_io.c:209
#define WVAL
Definition: hstore_io.c:207
static bool hstoreCheckKeyLength(size_t len, HSParser *state)
Definition: hstore_io.c:413
#define WEQ
Definition: hstore_io.c:208
#define SOFT_ERROR_OCCURRED(escontext)
Definition: miscnodes.h:52
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36

References elog(), ERROR, get_val(), hstoreCheckKeyLength(), hstoreCheckValLength(), palloc(), pg_strcasecmp(), PRSEOF, PRSSYNTAXERROR, repalloc(), SOFT_ERROR_OCCURRED, WDEL, WEQ, WGT, WKEY, and WVAL.

Referenced by hstore_in().

◆ PG_FUNCTION_INFO_V1() [1/13]

PG_FUNCTION_INFO_V1 ( hstore_from_array  )

◆ PG_FUNCTION_INFO_V1() [2/13]

PG_FUNCTION_INFO_V1 ( hstore_from_arrays  )

◆ PG_FUNCTION_INFO_V1() [3/13]

PG_FUNCTION_INFO_V1 ( hstore_from_record  )

◆ PG_FUNCTION_INFO_V1() [4/13]

PG_FUNCTION_INFO_V1 ( hstore_from_text  )

◆ PG_FUNCTION_INFO_V1() [5/13]

PG_FUNCTION_INFO_V1 ( hstore_in  )

◆ PG_FUNCTION_INFO_V1() [6/13]

PG_FUNCTION_INFO_V1 ( hstore_out  )

◆ PG_FUNCTION_INFO_V1() [7/13]

PG_FUNCTION_INFO_V1 ( hstore_populate_record  )

◆ PG_FUNCTION_INFO_V1() [8/13]

PG_FUNCTION_INFO_V1 ( hstore_recv  )

◆ PG_FUNCTION_INFO_V1() [9/13]

PG_FUNCTION_INFO_V1 ( hstore_send  )

◆ PG_FUNCTION_INFO_V1() [10/13]

PG_FUNCTION_INFO_V1 ( hstore_to_json  )

◆ PG_FUNCTION_INFO_V1() [11/13]

PG_FUNCTION_INFO_V1 ( hstore_to_json_loose  )

◆ PG_FUNCTION_INFO_V1() [12/13]

PG_FUNCTION_INFO_V1 ( hstore_to_jsonb  )

◆ PG_FUNCTION_INFO_V1() [13/13]

PG_FUNCTION_INFO_V1 ( hstore_to_jsonb_loose  )

◆ prseof()

static bool prseof ( HSParser state)
static

Definition at line 75 of file hstore_io.c.

76 {
77  errsave(state->escontext,
78  (errcode(ERRCODE_SYNTAX_ERROR),
79  errmsg("syntax error in hstore: unexpected end of string")));
80  /* In soft error situation, return false as convenience for caller */
81  return false;
82 }
#define errsave(context,...)
Definition: elog.h:260

References errcode(), errmsg(), and errsave.

◆ prssyntaxerror()

static bool prssyntaxerror ( HSParser state)
static

Definition at line 61 of file hstore_io.c.

62 {
63  errsave(state->escontext,
64  (errcode(ERRCODE_SYNTAX_ERROR),
65  errmsg("syntax error in hstore, near \"%.*s\" at position %d",
66  pg_mblen(state->ptr), state->ptr,
67  (int) (state->ptr - state->begin))));
68  /* In soft error situation, return false as convenience for caller */
69  return false;
70 }
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1024

References errcode(), errmsg(), errsave, and pg_mblen().

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 23 of file hstore_io.c.