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 "parser/scansup.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 88 of file hstore_io.c.

◆ GV_INVAL

#define GV_INVAL   1

Definition at line 87 of file hstore_io.c.

◆ GV_WAITESCESCIN

#define GV_WAITESCESCIN   4

Definition at line 90 of file hstore_io.c.

◆ GV_WAITESCIN

#define GV_WAITESCIN   3

Definition at line 89 of file hstore_io.c.

◆ GV_WAITVAL

#define GV_WAITVAL   0

Definition at line 86 of file hstore_io.c.

◆ PRSEOF

#define PRSEOF   return prseof(state)

Definition at line 73 of file hstore_io.c.

◆ PRSSYNTAXERROR

#define PRSSYNTAXERROR   return prssyntaxerror(state)

Definition at line 59 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:1540
Definition: regguts.h:323

Definition at line 48 of file hstore_io.c.

◆ WDEL

#define WDEL   4

Definition at line 211 of file hstore_io.c.

◆ WEQ

#define WEQ   2

Definition at line 209 of file hstore_io.c.

◆ WGT

#define WGT   3

Definition at line 210 of file hstore_io.c.

◆ WKEY

#define WKEY   0

Definition at line 207 of file hstore_io.c.

◆ WVAL

#define WVAL   1

Definition at line 208 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 326 of file hstore_io.c.

327 {
328  const Pairs *pa = a;
329  const Pairs *pb = b;
330 
331  if (pa->keylen == pb->keylen)
332  {
333  int res = memcmp(pa->key, pb->key, pa->keylen);
334 
335  if (res)
336  return res;
337 
338  /* guarantee that needfree will be later */
339  if (pb->needfree == pa->needfree)
340  return 0;
341  else if (pa->needfree)
342  return 1;
343  else
344  return -1;
345  }
346  return (pa->keylen > pb->keylen) ? 1 : -1;
347 }
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 1207 of file hstore_io.c.

1208 {
1209  char *ptr = src;
1210 
1211  while (ptr - src < len)
1212  {
1213  if (*ptr == '"' || *ptr == '\\')
1214  *dst++ = '\\';
1215  *dst++ = *ptr++;
1216  }
1217  return dst;
1218 }
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 93 of file hstore_io.c.

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

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

Referenced by parse_hstore().

◆ hstore_from_array()

Datum hstore_from_array ( PG_FUNCTION_ARGS  )

Definition at line 715 of file hstore_io.c.

716 {
717  ArrayType *in_array = PG_GETARG_ARRAYTYPE_P(0);
718  int ndims = ARR_NDIM(in_array);
719  int count;
720  int32 buflen;
721  HStore *out;
722  Pairs *pairs;
723  Datum *in_datums;
724  bool *in_nulls;
725  int in_count;
726  int i;
727 
728  Assert(ARR_ELEMTYPE(in_array) == TEXTOID);
729 
730  switch (ndims)
731  {
732  case 0:
733  out = hstorePairs(NULL, 0, 0);
734  PG_RETURN_POINTER(out);
735 
736  case 1:
737  if ((ARR_DIMS(in_array)[0]) % 2)
738  ereport(ERROR,
739  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
740  errmsg("array must have even number of elements")));
741  break;
742 
743  case 2:
744  if ((ARR_DIMS(in_array)[1]) != 2)
745  ereport(ERROR,
746  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
747  errmsg("array must have two columns")));
748  break;
749 
750  default:
751  ereport(ERROR,
752  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
753  errmsg("wrong number of array subscripts")));
754  }
755 
756  deconstruct_array_builtin(in_array, TEXTOID, &in_datums, &in_nulls, &in_count);
757 
758  count = in_count / 2;
759 
760  /* see discussion in hstoreArrayToPairs() */
761  if (count > MaxAllocSize / sizeof(Pairs))
762  ereport(ERROR,
763  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
764  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
765  count, (int) (MaxAllocSize / sizeof(Pairs)))));
766 
767  pairs = palloc(count * sizeof(Pairs));
768 
769  for (i = 0; i < count; ++i)
770  {
771  if (in_nulls[i * 2])
772  ereport(ERROR,
773  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
774  errmsg("null value not allowed for hstore key")));
775 
776  if (in_nulls[i * 2 + 1])
777  {
778  pairs[i].key = VARDATA(in_datums[i * 2]);
779  pairs[i].val = NULL;
780  pairs[i].keylen =
781  hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
782  pairs[i].vallen = 4;
783  pairs[i].isnull = true;
784  pairs[i].needfree = false;
785  }
786  else
787  {
788  pairs[i].key = VARDATA(in_datums[i * 2]);
789  pairs[i].val = VARDATA(in_datums[i * 2 + 1]);
790  pairs[i].keylen =
791  hstoreCheckKeyLen(VARSIZE(in_datums[i * 2]) - VARHDRSZ);
792  pairs[i].vallen =
793  hstoreCheckValLen(VARSIZE(in_datums[i * 2 + 1]) - VARHDRSZ);
794  pairs[i].isnull = false;
795  pairs[i].needfree = false;
796  }
797  }
798 
799  count = hstoreUniquePairs(pairs, count, &buflen);
800 
801  out = hstorePairs(pairs, count, buflen);
802 
803  PG_RETURN_POINTER(out);
804 }
#define ARR_NDIM(a)
Definition: array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define ARR_DIMS(a)
Definition: array.h:294
void deconstruct_array_builtin(ArrayType *array, Oid elmtype, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3678
signed int int32
Definition: c.h:494
#define VARHDRSZ
Definition: c.h:692
#define Assert(condition)
Definition: c.h:858
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#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:445
size_t hstoreCheckValLen(size_t len)
Definition: hstore_io.c:424
size_t hstoreCheckKeyLen(size_t len)
Definition: hstore_io.c:404
int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
Definition: hstore_io.c:356
int i
Definition: isn.c:73
#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 599 of file hstore_io.c.

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

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

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 563 of file hstore_io.c.

564 {
565  text *key;
566  text *val = NULL;
567  Pairs p;
568  HStore *out;
569 
570  if (PG_ARGISNULL(0))
571  PG_RETURN_NULL();
572 
573  p.needfree = false;
574  key = PG_GETARG_TEXT_PP(0);
575  p.key = VARDATA_ANY(key);
577 
578  if (PG_ARGISNULL(1))
579  {
580  p.vallen = 0;
581  p.isnull = true;
582  }
583  else
584  {
585  val = PG_GETARG_TEXT_PP(1);
586  p.val = VARDATA_ANY(val);
588  p.isnull = false;
589  }
590 
591  out = hstorePairs(&p, 1, p.keylen + p.vallen);
592 
593  PG_RETURN_POINTER(out);
594 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
long val
Definition: informix.c:670
Definition: c.h:687
#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 476 of file hstore_io.c.

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

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

◆ hstore_out()

Datum hstore_out ( PG_FUNCTION_ARGS  )

Definition at line 1222 of file hstore_io.c.

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

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

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

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 1293 of file hstore_io.c.

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

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 1394 of file hstore_io.c.

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

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 1339 of file hstore_io.c.

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

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 1439 of file hstore_io.c.

1440 {
1441  HStore *in = PG_GETARG_HSTORE_P(0);
1442  int i;
1443  int count = HS_COUNT(in);
1444  char *base = STRPTR(in);
1445  HEntry *entries = ARRPTR(in);
1446  JsonbParseState *state = NULL;
1447  JsonbValue *res;
1448 
1449  (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1450 
1451  for (i = 0; i < count; i++)
1452  {
1453  JsonbValue key,
1454  val;
1455 
1456  key.type = jbvString;
1457  key.val.string.len = HSTORE_KEYLEN(entries, i);
1458  key.val.string.val = HSTORE_KEY(entries, base, i);
1459 
1460  (void) pushJsonbValue(&state, WJB_KEY, &key);
1461 
1462  if (HSTORE_VALISNULL(entries, i))
1463  {
1464  val.type = jbvNull;
1465  }
1466  else
1467  {
1468  val.type = jbvString;
1469  val.val.string.len = HSTORE_VALLEN(entries, i);
1470  val.val.string.val = HSTORE_VAL(entries, base, i);
1471  }
1472  (void) pushJsonbValue(&state, WJB_VALUE, &val);
1473  }
1474 
1476 
1478 }
@ 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:92
JsonbValue * pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *jbval)
Definition: jsonb_util.c:566

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 1482 of file hstore_io.c.

1483 {
1484  HStore *in = PG_GETARG_HSTORE_P(0);
1485  int i;
1486  int count = HS_COUNT(in);
1487  char *base = STRPTR(in);
1488  HEntry *entries = ARRPTR(in);
1489  JsonbParseState *state = NULL;
1490  JsonbValue *res;
1491  StringInfoData tmp;
1492 
1493  initStringInfo(&tmp);
1494 
1495  (void) pushJsonbValue(&state, WJB_BEGIN_OBJECT, NULL);
1496 
1497  for (i = 0; i < count; i++)
1498  {
1499  JsonbValue key,
1500  val;
1501 
1502  key.type = jbvString;
1503  key.val.string.len = HSTORE_KEYLEN(entries, i);
1504  key.val.string.val = HSTORE_KEY(entries, base, i);
1505 
1506  (void) pushJsonbValue(&state, WJB_KEY, &key);
1507 
1508  if (HSTORE_VALISNULL(entries, i))
1509  {
1510  val.type = jbvNull;
1511  }
1512  /* guess that values of 't' or 'f' are booleans */
1513  else if (HSTORE_VALLEN(entries, i) == 1 &&
1514  *(HSTORE_VAL(entries, base, i)) == 't')
1515  {
1516  val.type = jbvBool;
1517  val.val.boolean = true;
1518  }
1519  else if (HSTORE_VALLEN(entries, i) == 1 &&
1520  *(HSTORE_VAL(entries, base, i)) == 'f')
1521  {
1522  val.type = jbvBool;
1523  val.val.boolean = false;
1524  }
1525  else
1526  {
1527  resetStringInfo(&tmp);
1528  appendBinaryStringInfo(&tmp, HSTORE_VAL(entries, base, i),
1529  HSTORE_VALLEN(entries, i));
1530  if (IsValidJsonNumber(tmp.data, tmp.len))
1531  {
1532  Datum numd;
1533 
1534  val.type = jbvNumeric;
1536  CStringGetDatum(tmp.data),
1538  Int32GetDatum(-1));
1539  val.val.numeric = DatumGetNumeric(numd);
1540  }
1541  else
1542  {
1543  val.type = jbvString;
1544  val.val.string.len = HSTORE_VALLEN(entries, i);
1545  val.val.string.val = HSTORE_VAL(entries, base, i);
1546  }
1547  }
1548  (void) pushJsonbValue(&state, WJB_VALUE, &val);
1549  }
1550 
1552 
1554 }
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:628
#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:61
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 404 of file hstore_io.c.

405 {
406  if (len > HSTORE_MAX_KEY_LEN)
407  ereport(ERROR,
408  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
409  errmsg("string too long for hstore key")));
410  return len;
411 }
#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 414 of file hstore_io.c.

415 {
416  if (len > HSTORE_MAX_KEY_LEN)
417  ereturn(state->escontext, false,
418  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
419  errmsg("string too long for hstore key")));
420  return true;
421 }
#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 424 of file hstore_io.c.

425 {
427  ereport(ERROR,
428  (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
429  errmsg("string too long for hstore value")));
430  return len;
431 }
#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 434 of file hstore_io.c.

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

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 445 of file hstore_io.c.

446 {
447  HStore *out;
448  HEntry *entry;
449  char *ptr;
450  char *buf;
451  int32 len;
452  int32 i;
453 
454  len = CALCDATASIZE(pcount, buflen);
455  out = palloc(len);
456  SET_VARSIZE(out, len);
457  HS_SETCOUNT(out, pcount);
458 
459  if (pcount == 0)
460  return out;
461 
462  entry = ARRPTR(out);
463  buf = ptr = STRPTR(out);
464 
465  for (i = 0; i < pcount; i++)
466  HS_ADDITEM(entry, buf, ptr, pairs[i]);
467 
468  HS_FINALIZE(out, pcount, buf, ptr);
469 
470  return out;
471 }
#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 356 of file hstore_io.c.

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

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 215 of file hstore_io.c.

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

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

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

◆ prssyntaxerror()

static bool prssyntaxerror ( HSParser state)
static

Definition at line 62 of file hstore_io.c.

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

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

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 24 of file hstore_io.c.